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:

while [ $SECONDS -lt $end ];
   # process some queue...
   sleep 5

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


 #! /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 !

  • 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

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.


$ dash -c 'echo "[$SECONDS]"'
$ bash -c 'echo "[$SECONDS]"'
$ 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.

  • 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

Change the first line of the script to:


If you are on Debian and (1) like bash and (2) know the script was written for a system that linked /bin/bash under /bin/sh. I gave up on trying to attempt universal /bin/sh scripts, it's a useless exercise if all the system under your control support bash.

I know it's an old question, but nobody gave the simplest answer.

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.