1

I am working on an audio visual art installation, using a Raspberry Pi with Raspbian Jessie. The audio or video is started after login via a bash script. This script runs fine on its own.

My issue has been with trying to schedule the loop to run only during certain times of the day using an if statement. This has been placed at the beginning on the loop to check the time before a new file would start.

HOUR=$(date +"%H")
echo "The hour is $HOUR"
if [ $HOUR -gt 22 || $HOUR-lt 8 ]
then
        sleep 60
        continue
fi

I have declared HOUR as an integer with declare -i HOUR at the beginning of the script.

The script outputs this error, then continues.

./start_audio.sh: line 49: 13: command not found

I believe the variable is set correctly because $HOUR [13] is shown in the error. So why is $hour being interpreted as a command when it has been declared as an integer?

Tried changes like adding quotes or removing spaces, as answers to other questions have suggested.

codeforester
  • 39,467
  • 16
  • 112
  • 140
Starbuck
  • 143
  • 8

3 Answers3

3

Enclose your variables in double quotes (not required here, but as a general best practice) and and separate out the checks into two with a || in between (-o is mostly deprecated):

if [ "$HOUR" -gt 22 ] || [ "$HOUR" -lt 8 ]

Or, you can use [[ ]]:

if [[ "$HOUR" -gt 22 || "$HOUR" -lt 8 ]]

Even better, use arithmetic operator, (( ... )):

if ((HOUR > 22 || HOUR < 8))

Related:

codeforester
  • 39,467
  • 16
  • 112
  • 140
3

The shell builtin [ (test) or the external one does not support short circuit evaluation operators within their construct.

You need to use the bash keyword, [[:

[[ $HOUR -gt 22 || $HOUR -lt 8 ]]

Or break the logic in two parts:

[ $HOUR -gt 22 ] || [ $HOUR -lt 8 ]

While we are at it, you should quote your variable expansions to prevent word splitting and pathname expansion:

[ "$HOUR" -gt 22 ] || [ "$HOUR" -lt 8 ]

I have assumed that $HOUR-lt 8 is a typo as it should be $HOUR -lt 8.

heemayl
  • 39,294
  • 7
  • 70
  • 76
  • Quoting will not hurt, but I do not think it adds anything : if the HOUR variable is to contain spaces (requiring quoting), then the -gt and -lt operators will fail with ugly results as well. If the date command cannot be trusted to return only digits, then it has to be checked prior to attempting the comparisons. – Fred Jan 17 '17 at 03:55
  • @Fred Consider `HOUR='foo -o 3`. If you don't quote `$HOUR`, then `[` succeeds despite `$HOUR` not being an integer at all, never mind being less than 8 or greater than 22. – chepner Jan 17 '17 at 12:35
  • True. I always use double brackets [[ ]], which are not exposed to this problem, and I forgot the word splitting performed by the single bracket test command. – Fred Jan 17 '17 at 12:47
1

I do not think you can use the || operator in a standard test [ ].

Try replacing || by -o, or using the double-bracketed [[ ]] conditional (bash-specific).

Fred
  • 6,590
  • 9
  • 20
  • `-o` is deprecated a long time ago. – heemayl Jan 17 '17 at 03:58
  • I really am no expert regaring this, but -o seems to be part of the POSIX specification for the "test" command... I would be surprised if bash had deprecated that operator for its internal builtin version (see http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html) – Fred Jan 17 '17 at 04:12
  • `-o` is an extension to the POSIX specification that is considered obsolete. New code should not use it. – chepner Jan 17 '17 at 04:25
  • Is this just common knowledge, or is there some reference source where such guidelines are documented? – Fred Jan 17 '17 at 04:29
  • They're actually marked "obsolescent" in the [POSIX spec](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html) (click on the ["OB XSI"](http://pubs.opengroup.org/onlinepubs/9699919799/help/codes.html#OB%23XSI) link). – Benjamin W. Jan 17 '17 at 05:13
  • Hidden in plain sight, I just did not pay attention to this when I glanced at the spec. Thanks! – Fred Jan 17 '17 at 05:17