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 ]]
Related
I wrote below piece of code to calculate the date after a given date:
date=$DATE_FINAL
declare -a max_month=(0 31 28 31 30 31 30 31 31 30 31 30 31)
eval $(echo $date|sed 's!\(....\)\(..\)\(..\)!year=\1;month=\2;day=\3!')
(( year4=year%4 ))
(( year100=year%100 ))
(( year400=year%400 ))
if [ \( $year4 -eq 0 -a \
$year100 -ne 0 \) -o \
$year400 -eq 0 ]
then
declare -a max_month=(0 31 28 31 30 31 30 31 31 30 31 30 31)
fi
day=$((day+1))
if [ $day -gt ${max_month[$month]} ] >| /wload/baot/home/baoted9/logs_bde27_conversion_1/ataa_display.logs 2>&1
then
day=1
month=$((month+1))
if [ $month -gt 12 ]
then
year=$((year+1))
month=1
fi
fi
if [ $month -eq "08" ] || [ $month -eq "09" ]
then
future_date_final=$(echo $year"$month"$day)
else
future_date_final=$(printf "%4.4d%2.2d%2.2d" $year $month $day)
fi
echo "this is your final business date $future_date_final"
It calculates the date correctly however throws an error at the end of the code as below -
line 79: 08: value too great for base (error token is "08")
It just looks too ugly, not sure how to remove it as otherwise code is working fine, tried redirecting it to a log file still appearing.
Also, I am facing issue with below code for a plain cd command with code highlighted in red -
echo "pset date $Param_date_1"
cd /wload/baot/home/baotasa0/sandboxes_finance/ext_ukba_bde/pset >| /wload/baot/home/baoted9/logs_bde27_conversion_1/at_display.logs 2>&1
sh UKBA_publish.sh UKBA $Param_date_1 3 >| /wload/baot/home/baoted9/logs_bde27_conversion_1/ate_display.logs 2>&1
Error is -
./auto2.sh: line 190: syntax error: unexpected end of file
The problem is, that if you're using $((val+1)) where $val is beginning with a 0, then bash isn't operating on decimal base but on octal base. Since 08 isn't a valid number in octal base, it complains.
You can force decimal representation by writing
$((10#$val+1))
Please note, that by doing so, any preceding zeros are removed. If you need to have a representation with preceding zero, just use
val=$(printf '%02d' $((10#$val+1)))
For reference, see the bash manual:
Constants with a leading 0 are interpreted as octal numbers. A leading ‘0x’ or ‘0X’ denotes hexadecimal. Otherwise, numbers take the form [base#]n, where the optional base is a decimal number between 2 and 64 representing the arithmetic base, and n is a number in that base. If base# is omitted, then base 10 is used. When specifying n, the digits greater than 9 are represented by the lowercase letters, the uppercase letters, ‘#’, and ‘_’, in that order. If base is less than or equal to 36, lowercase and uppercase letters may be used interchangeably to represent numbers between 10 and 35.
P.S.: This is a very good article about falsehoods programmers believe about time I had to read myself. If possible, try to use date -d instead of doing manual date arithmetic. You can use for instance date -d "+5 days" +%d.%m.%Y to get the date in five days.
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!
Seagate hard drives display a code instead of the manufacturing date. The code is described here and an online decoder is available here.
In short, it's a 4 or 5 digit number of the form YYWWD or YYWD, where:
YY is the year, 00 is year 1999
W or WW is the week number beginning 1
D is day of week beginning 1
Week 1 begins on the first saturday of July in the stated year
Examples
06212 means Sunday 20 November 2005
0051 means Saturday 31 July 1999
How can this be decoded in a bash script ?
This is what I did, it should work:
#!/bin/bash
DATE=$1
REGEX="^(..)(..?)(.)$"
[[ $DATE =~ $REGEX ]]
YEAR=$(( ${BASH_REMATCH[1]} + 1999 ))
WEEK=$(( ${BASH_REMATCH[2]} - 1))
DAYOFWEEK=$(( ${BASH_REMATCH[3]} - 1))
OFFSET=$(( 6 - $(date -d "$YEAR-07-01" +%u) ))
DATEOFFIRSTSATURDAY=$(date -d "$YEAR-7-01 $OFFSET days" +%d)
FINALDATE=`date -d "$YEAR-07-$DATEOFFIRSTSATURDAY $WEEK weeks $DAYOFWEEK days"`
echo $FINALDATE
It worked for the two dates given above...
If you want to customize the date output, add a format string at the end of the FINALDATe assignment.
Here is a short script, it takes two arguments: $1 is the code to convert and $2 is an optional format (see man date), otherwise defaulted (see code).
It uses the last Saturday in June instead of the first one in July because I found it easer to locate and it allowed me to just add the relevant number of weeks and days to it.
#!/bin/bash
date_format=${2:-%A %B %-d %Y}
code=$1
[[ ${#code} =~ ^[4-5]$ ]] || { echo "bad code"; exit 1; }
let year=1999+${code:0:2}
[[ ${#code} == 4 ]] && week=${code:2:1} || week=${code:2:2}
day=${code: -1}
june_last_saturday=$(cal 06 ${year} | awk '{ $6 && X=$6 } END { print X }')
date -d "${year}-06-${june_last_saturday} + ${week} weeks + $((${day}-1)) days" "+${date_format}"
Examples:
$ seadate 06212
Sunday November 20 2005
$ seadate 0051
Saturday July 31 1999
I created a Seagate Date Code Calculator that actually works with pretty good accuracy. I've posted it here on this forum for anyone to use: https://www.data-medics.com/forum/seagate-date-code-conversion-translation-tool-t1035.html#p3261
It's far more accurate than the other ones online which often point to the entirely wrong year. I know it's not a bash script, but will still get the job done for anyone else who's searching how to do this.
Enjoy!
This question is related to the thread here:
Today's date, minus X days in shell script
But because I'm now manipulating the variable, I started another thread.
As described above, I need to get today's date minus 200 days, with the Year, Month, and Day in separate variables (in this question I'll use 200, though in the other it's 222). However, I need to represent January as 0, February as 1 (or 01), March as 2 (or 02), etc... I tried this:
MONTHS200=$(date -j -v-200d -v-1m +"%m")
if ${MONTHS200}=01; then
${MONTH200}=0
else ${MONTHS200}=${MONTH200}
fi
But I get the error ./update_newdateformat.sh: line 20: 12=01: command not found ./update_newdateformat.sh: line 23: 12=: command not found The -v-1m works for all months except January, because it goes to 12, instead of 0
Here's how to shift all the month number down by 1 n your script:
MONTHS200=$(date -j -v-320d +"%m")
# Remove leading zero if there is one, so it doesn't cause problems later
MONTHS200=${MONTHS200#0}
MONTHS200=$((MONTHS200-1))
Here is how to use if and = (assignment) syntax in shell:
if [[ "${MONTHS200}" == "01" ]]; then
MONTHS200="0"
else
MONTHS200=${AnotherVariable}
fi
Note that for numerical comparisons, you need to use:
-eq instead of ==
-ne instead of !=
-lt instead of <
-le instead of <=
-gt instead of >
-ge instead of >=
For example:
if [[ "${MONTHS200}" -eq 1 ]]; then
I would take advantage of bash features (I assume OSX bash is recent enough -- I might be wrong). You only need to call date once with
read year month day < <(date -j -v-200d +"%Y %m %d")
month=$(( 10#$month - 1 ))
You avoid the octal issue by forcing bash to use base-10
I need to write a shell script that will create a list of 5 minutes interval times.
00-00
00-05
00-10
00-15
...
...
23-50
23-55
Here are the commands I have started with.
# date
Fri Sep 21 18:14:35 IST 2012
# date '+%H-%M'
18-14
# date '+%H-%M' --date='5 minute ago'
18-18
How do I write a script to generate the list?
If it is too complicated, I will do it manually since it is one time task.
Update:
The following script is working. But it will generate single digits like 7-5 should actually be 07-05
#!/bin/sh
for hour in `seq 0 24`
do
for minute in `seq 0 5 59`
do
echo $hour-$minute
done
done
A simple bash solution (version 4 or later):
printf "%s\n" {00..23}-{00..55..5}
If you need to start at a given date, you can use:
ITERATIONS=100 # adjust here
D=$(date +%s)
for ((i=0; i<$ITERATIONS; i++))
do
date '+%H-%M' -d #$((D+5*60*i))
done
The following shell scripting is returning the required data
#!/bin/sh
for hour in `seq -w 0 24`
do
for minute in `seq -w 0 5 59`
do
echo $hour-$minute
done
done