Here's an easy way to understand your while
problems:
The [
is an actual Unix command. Do ls /bin/[
and you'll see. It's a link to the /bin/test
command. Do a man test
from the command line and see the various tests that can be done.
What the while
does is execute the command you give it, and if it returns a zero exit status, the while
statement is considered true and the statement will continue. You can do things like this:
while sleep 2
do
echo "I slept for two seconds"
done
All the test
command does is do some sort of testing (file tests, tests of equality, etc.) and return a zero if the statement is true and a non-zero otherwise:
$ test 2 -gt 3
$ echo $?
1 <- That statement is false
$ [ 2 -lt 3 ] #The test command using square brackets
$ echo $?
0 <- That statement is true.
Take a look at the manpage for test
and you'll see all valid tests. This:
while [ date +"%T" -gt '06:00:00' && date +"%T" -lt '21:00:00']
is the same as
while test date +"%T" -gt '06:00:00' && date +"%T" -lt '21:00:00'
Let's go through a few things here:
- date + %T is not a valid operator for the
test
command.
The test
command can't execute a command internally. What you need to do is to put that command in $(..)
and probably use quotes to play it safe. Thus:
while test "$(date +"%T")" -gt '06:00:00' && "$(date +"%T")" -lt '21:00:00'
- The
&&
is not a valid operator in thetest
command. What you probably want is-a
which is the and conjunctive for stringing together two tests intest
.
This would give you:
while test $(date +"%T") -gt '06:00:00' -a "$(date +"%T")" -lt '21:00:00'
There are two separate greater than test operators for comparisons. One is for strings and one is for integers. The
-gt
is the test for integers. Since you're dealing with strings, you need to use>
:while test "$(date +"%T")" > '06:00:00' -a "$(date +"%T")" < '21:00:00'
As an alternative, you could have also used the &&
conjunctive instead of -a
, but each side of the &&
would have to be separate test statements:
while test "$(date +"%T")" > '06:00:00' && test "$(date +"%T")" < '21:00:00'
Now, let's convert the test
syntax back to [...]
because it's easier on the eyes
while [ "$(date +"%T")" > '06:00:00' -a "$(date +"%T")" < '21:00:00' ]
OR
while [ "$(date +"%T")" > '06:00:00' ] && [ "$(date +"%T")" < '21:00:00' ]
By the way, the internal [[...]]
is better -- especially with the >
sign since it can be interpreted by the shell as a file redirect.
while [[ "$(date +"%T")" > '06:00:00' -a "$(date +"%T")" < '21:00:00' ]]
OR
while [[ "$(date +"%T")" > '06:00:00' ]] && [[ "$(date +"%T")" < '21:00:00' ]]