date comparison not working properly in shell script - shell

I want to compare dates in shell script.
The logic I am using as below :
$date_1="Tue Nov 25 23:50:01 CST 2014"
$date_2=$(date)
if [ $date_2 -eq $date_1 ] ; then
echo "$date2 is equal to $date_1"
else
echo "$date2 is not equal to $date_1"
fi
However when I am executing the script using crontab for every minute,
I got the below message in log which is not correct :
Tue Nov 25 23:50:01 CST 2014 is not equal to Tue Nov 25 23:50:01 CST 2014
Could you please help me out of this embarrassing situation?

Assuming this job is running every minute. You can do:
date_1="Tue Nov 25 23:50:01 CST 2014"
dt1=$(date -d "$date_1" '+%Y%m%d%H%M')
dt2=$(date '+%Y%m%d%H%M')
if [ "$dt1" -eq "$dt2" ]; then
echo "$dt2 is equal to $date_1"
else
echo "$dt2 is not equal to $date_1"
fi

Best thing would be to format your date strings to look like numbers, starting with year, then month, etc. You probably would want to code a greater than or equal, or less than or equal, in case cron skips a second now or then:
date_1=$(date +%Y%m%d%H%M%S)
sleep 10
date_2=$(date +%Y%m%d%H%M%S)
if [ $date_2 -ge $date_1 ] ; then
echo "$date_2 is greater than or equal to $date_1"
else
echo "$date_2 is less than $date_1"
fi
Output:
20141126063044 is greater than or equal to 20141126063034
Beware you don't want the $ in front of the variable when you are setting it!

Related

Multiple dates are not working with epoch comparison in bash

printf "%s\n" "$EXPDATES"
Jul 12 2019 12:00:00
Jul 12 2019 12:00:00
Jul 12 2019 12:00:00
Jun 18 2019 12:00:00
Aug 8 2019 12:00:00
May 8 2018 00:00:00
The above o/p I'm getting from "for loop" and passing all the dates (including one empty line) in same format to another "for loop" to convert and compare with current "epoch".
curr_epoch=$(date +%s)
for expdate in "${EXPDATES[#]}"; do
exp_epoch=$(date +%s -d "$expdate")
if (( curr_epoch > exp_epoch )); then
echo "$expdate in future."
else
echo "$expdate in past."
fi
done
Here I'm not getting proper output for all the dates. "$expdate" in echo line doesn't return anything.
I'm not sure whether for-loop is comparing all the dates.
Can anyone please tell me how to compare all the dates and show output with all the dates compared?
You are missing ending quotes for the echo lines in your code. This will work:
for expdate in "${EXPDATES[#]}"; do
exp_epoch=$(date +%s -d "$expdate")
if (( curr_epoch > exp_epoch )); then
echo "$expdate in future."
else
echo "$expdate in past."
fi
done

cutting out the hour part (not in 24 hour time) of a date?

My problem is with cutting the hour portion of the date out.
I am not allowed to use date commands only cut!!!!!
Suppose the date command at that time reads
Tues Apr 26 17:07:49 PDT 2017
then it should print out
5:07
I am having a lot of trouble because it is not recognizing a read on an int but rather a string. Been bugging me a long time now...
Here is my code thus far:
today=$(date)
echo The date right now is "$today"
echo "The time right now is $(printf '%s\n' "$today" | cut -c 11-19)"
let hour=${today:11:2}
let minute=${today:13:2}
if [[ ${hour} -ge 43200 ]]
then
let answer=hour-12
echo "The correct time is $answer:$minute pm"
fi
I calculated 43200 from the number of seconds at 12:00pm
Current output is:
The date right now is Wed Apr 26 21:47:39 PDT 2017
The time right now is 21:47:39
let hour=${today:11:2}
let minute=${today:13:2}
You have the following string format (with positions):
1 2
0123456789012345678901234567
Wed Apr 26 21:47:39 PDT 2017
^ ^
That means the two characters at offset 11 are 17 (correct) but the minute is being extracted at offset 13, which is :0. The correct extraction for minute would be ${today:14:2}.

How can I compare the hour to a string/number in bash?

We have a server which we use to run Selenium tests with our extension (for Chrome and Firefox). We run the Selenium tests every 2 hours. I want to run different tests after 14:00 than before 14:00. I have this variable:
start_hour=`TZ='Asia/Tel_Aviv' date +"%H"`
And I know how to compare it to a specific hour, such as 08:00 AM (it's a string):
if [ "$start_hour" = "08" ]; then
...
fi
But how do I check if this variable shows an hour after 14:00 (including 14:00), or before 14:00? Can I compare strings in bash and how? I just want to check if $start_hour is >= "14", or not?
Is the answer different if I want to check after 08:00 AM or before?
To perform greater or less-than comparisons, the test operations -gt, -le, -ge, and -le exist.
start_hour=$(TZ='Asia/Tel_Aviv' date '+%k')
[ "$start_hour" -ge 8 ]
Note the use of %k vs %H, and 8 vs 08 -- a leading 0 can prevent your numbers from being interpreted as decimal.
Similarly, in native bash syntax, for a numeric comparison:
start_hour=$(TZ='Asia/Tel_Aviv' date '+%k')
(( start_hour >= 8 ))
If your shell is bash, and not /bin/sh, and you truly do want an ASCII-sort string comparison, you can use > and < inside of [[ ]]:
start_hour=$(TZ='Asia/Tel_Aviv' date '+%H')
[[ $start_hour > 08 || $start_hour = 08 ]]

Ksh date validation YYYYMMDD

I'm having a weird problem with the below simple date validation.
It fails validation for some dates.
An example is: 20140717
Other dates pass validation ok? i.e: 20140727
validate_date()
{
typeset my_date=$1
if [[ $my_date = [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]] ; then
return 0;
else
return 1
fi
}
Can someone run it on ksh and see if the same happens?
I cannot see why the code is given improper result for your input .
I think one of the better ways of validating for date would be to use date -d "datestring"
it return the time displayed by the string in case of success and error in case date validation fails
so after date -d "datestring" .. you can check the value of $? so know success or failure of validation .
for example
ajay#pavilion:~$ date -d 20140730
Wed Jul 30 00:00:00 IST 2014
ajay#pavilion:~$ echo $?
0
ajay#pavilion:~$ date -d 20140750
date: invalid date ‘20140750’
ajay#pavilion:~$ echo $?
1
ajay#pavilion:~$

why can I not save the output of this awk statement to a variable

I am currently trying to make a variable name that would consist of another variable
while [ "$countf" -le 9 ]; do
vname=$( echo fcp"$countf" )
$vname=$( awk -F, -vs="\$fc$countf" '{for (i=1;i<=NF;i++)if($i~"^"s"$"){print i;exit;}}{print "not found"}' <<< $first_line )
countf=$(( countf + 1 ))
done
although when I go to execute the the script that includes the code, something along the lines of the following is outputted:
fcp1=not: command not found
fcp1 being the content of the vname variable. I've tried several different solutions but have not gotten anything to work yet as of right now, if someone could point out what I am doing wrong though I would really appreciate it, thanks.
You've made a mistake, instead of
$vname=$(... )
you should use :
vname=$(... )
You can't use $ in the left of assignation like this.
A workaround is to use declare if you want to do indirect variable references :
$ x=var
$ declare $x=test
$ echo $var
test
NOTE
As mentioned in discussion in this thead, don't use eval to do this. eval is a common misspelling of evil. See http://mywiki.wooledge.org/BashFAQ/048
You need to use eval if you're going to build a variable name from parts like that:
$ cat tst.sh
countf=0
while (( $countf <= 2 ))
do
vname="fcp${countf}"
eval $vname="\$(date)"
countf=$(( countf + 1 ))
sleep 1
done
echo "$fcp0"
echo "$fcp1"
echo "$fcp2"
$ ./tst.sh
Mon Nov 19 21:22:05 CST 2012
Mon Nov 19 21:22:06 CST 2012
Mon Nov 19 21:22:08 CST 2012
but you should seriously consider an array instead:
$ cat tst.sh
countf=0
while (( $countf <= 2 ))
do
fcpArr[$countf]="$(date)"
countf=$(( countf + 1 ))
sleep 1
done
echo "${fcpArr[0]}"
echo "${fcpArr[1]}"
echo "${fcpArr[2]}"
$ ./tst.sh
Mon Nov 19 21:22:48 CST 2012
Mon Nov 19 21:22:50 CST 2012
Mon Nov 19 21:22:51 CST 2012

Resources