Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

As I was trying to execute a script in a new environment, I came up with this error:

[: 10: -lt: unexpected operator

Here is the painful part of the script:

end=$((SECONDS+60))
while [ $SECONDS -lt $end ];
do
   # process some queue...
   sleep 5
done

Origin system: Amazon Linux AMI release 2013.09 (cpe:/o:amazon:linux:2013.09:ga)

Destination system: Debian version 6.0.7

I can read that shell / bash / dash versions can vary, but this is still quite obscure to me. I tried to specify the correct shell on the first line of the script:

 #! /bin/bash

or

 #! /bin/sh

no chance...

I could also find out that users had similar error messages when using operator == instead of =. What would be the correct replacement for -lt then ? Is there any other solutions ? Any hint is warmly welcome !

share|improve this question
2  
Is $SECONDS actually set to a value? –  Michael Hampton Oct 2 '13 at 16:58
    
@MichaelHampton if I echo $SECONDS, I get a value that is increasing at a speed that reasonably looks like seconds. On both systems (though on one I get 1568..., and on the other 4511...). –  mika Oct 2 '13 at 17:08
    
@MichaelHampton It seems I did not call the echo in the correct way. See Dennis Williamson answer below for details :) –  mika Oct 3 '13 at 8:41
add comment

1 Answer 1

up vote 3 down vote accepted

Dash doesn't support the $SECONDS auto-incrementing variable found in Bash. Because the variable has no value, the test command ([) sees an unset variable before the operator and produces the error you posted.

Demonstration:

$ dash -c 'echo "[$SECONDS]"'
[]
$ bash -c 'echo "[$SECONDS]"'
[0]
$ dash -c '[ $var -lt 3 ]'
dash: 1: [: -lt: unexpected operator
$ dash -c 'var=1; [ $var -lt 3 ]'
$

You can use the date command in order to do the check instead. Be aware that this could be expensive since you could call an external utility many times.

There may be other ways to accomplish what you're trying to do, but you don't say what that is.

Please also see BashFAQ/068.

share|improve this answer
    
Excellent proof ! Thanks a lot ! –  mika Oct 3 '13 at 8:36
    
About the context... I run this script every minute in the cron. This way, I get my task to run, and pause for 5 seconds, and run again... And stop launching agin after a minute. If the new script launched by cron overlaps the previous one, this is fine. Why doing this ? If my script crashes, I can make sure it starts again at most a minute later (with a new task, that will not crash). I agree there must be more elegant ways to achieve this. This is the script I've been using so far though, and it does the job, so... Thanks a lot for helping to fix it ! –  mika Oct 3 '13 at 9:18
    
So using $(date '+%s') instead of SECONDS works well in this context. Since I wait between each loop, expensive external calls are not a worry :) –  mika Oct 3 '13 at 9:23
1  
@mika: Please see Process Management (the section title refers to "game server" but the principle is more broadly applicable). –  Dennis Williamson Oct 3 '13 at 12:29
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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