4

I am trying to check running time and if it is more than an hour return an error, but the code returns false positives intermittently. In firstRun.sh, I read time as:

export START_H=`date +%H`
export START_M=`date +%m`

and in secondRun.sh I check the time as follows:

CURRENT_H=`date +%H`
CURRENT_M=`date +%M`
TIME=`expr $CURRENT_H - $START_H`

if [ $TIME -gt 0 ] && [ $START_M -lt $CURRENT_M ]; then
    echo "boot time is more than an hour"
fi

Can anyone help me find where the problem might be? Is there any difference between using && and -a in if statement? Or any difference between using [] and ()?

  • && is a shell control operator. -a is an argument to the test command ([). You should store start time in seconds (%s) and compare that way. – jordanm Apr 19 '15 at 20:44
  • does it make any difference to use '&&' in if statement rather than -a ? – user3705440 Apr 19 '15 at 20:47
  • 1
    @user3705440 Yes. && terminates a command, -a is part of a command (ie. the test command and its synonyms). – Chris Down Apr 19 '15 at 20:54
  • secondRun.sh can not access variables set by firstRun.sh. Try to source firstRun.sh. – Cyrus Apr 19 '15 at 21:28
  • The && is standard (defined by POSIX). But -a and having more than four arguments in test or [ is non-standard; you cannot count on it to work in a POSIX complient (standard) shell. – Janis Apr 19 '15 at 21:29
8
export BOOT_TIME=$(date +%s)
current=$(date +%s)
(( current - BOOT_TIME >3600 ))  && echo "More than an hour"

%s returns seconds since 1970-01-01 00:00:00 UTC.

Discussion: why seconds are better

Suppose, for example, that the start (boot) time is 23:00 and the current time is 00:23. Then, $TIME is negative and this won't work:

if [ $TIME -gt 0 ] && [ $START_M -lt $CURRENT_M ]; then
    echo "boot time is more than an hour"
fi

Similarly, suppose that the start time is 12:03 and the current time is 14:00. Then, the above won't work either, this time because of the minutes test.

|improve this answer|||||
  • Should include --utc from roaimas answer! Otherwise you can get screwed by leap-seconds and other stuff... – Falco Apr 20 '15 at 11:08
  • 2
    @Falco, I've been thinking about this and I'm pretty sure that --utc flag is irrelevant for %s (Seconds since the Epoch). It's just habit on my part to include it whenever I do date maths. – roaima Apr 20 '15 at 11:23
  • @Falco My tests confirm Roaima's comment. On my GNU+Linux system, date --utc +%s and date +%s give the exact same answer even though my timezone is far different from UTC and is currently in daylight savings. – John1024 Apr 20 '15 at 18:32
3

Two concerns here

  1. You have a potential race condition when setting the Hour and Minute of the current time in separate statements (consider the rollover of minutes at the top of the hour).

  2. In your first script snippet you are using %m for minutes (but this is actually months). In your second you are using %M.

My recommendation is that you would be better with HHMM=$(date +'%H %M') and then splitting that into two parts. Even better, take the time as a combined value of seconds since the Epoch SECONDS=$(date --utc +'%s') and allow for 3600 seconds in the hour. (The --utc part avoids getting caught by local time changes twice a year.)

|improve this answer|||||
  • + 1 for noticing the race condition and the %m issue. – John1024 Apr 20 '15 at 18:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.