I am trying to write a bash script that will loop if the time is after certain time and before a certain time. Here is what i have got but it gives me an error;
#!/bin/bash
while [ date +"%T" -gt '06:00:00' && date +"%T" -lt '21:00:00'];
do
##echo `php mainstatquery.php`
echo "Hello World";
sleep 5;
done
and this is the error
./timer.sh: line 3: [: missing `]'
If anyone could point me in the right direction.
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:
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'
&&
is not a valid operator in the test
command. What you probably want is -a
which is the and conjunctive for stringing together two tests in test
.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' ]]