views:

10728

answers:

4

The following code gives

[: -ge: unary operator expected

when

i=0

if [ $i -ge 2 ]
                then
                #some code
                fi

why?

A: 

Your piece of script works just great. Are you sure you are not assigning anything else before the if to "i"?

A common mistake is also not to leave a space after and before the square brackets.

Fernando Miguélez
+6  A: 

It doesn't give me that error. Nonetheless, if you're using bash it's better to use the builtin [[ than the test ([) command.

if [[ $i -ge 2 ]]
PEZ
Works like a charm, thank you! :)
Filip Ekberg
this is not portable. Just do the right thing and quote $i, i.e. if [ "$i" -ge 2 ] ; then ...
vladr
Well it answars my question and it works :)
Filip Ekberg
+3  A: 

Judging from the error message the value of i was the empty string when you executed it, not 0.

starblue
+12  A: 

Your problem arises from the fact that $i does not have a non-blank value when your statement fails. Always quote your variables when performing comparisons if there is the slightest chance that one of them may be empty, e.g.:

if [ "$i" -ge 2 ] ; then
  ...
fi

This is because of how the shell treats variables. Assume the original example,

if [ $i -ge 2 ] ; then ...

The first thing that the shell does when executing that particular line of code is substitute the value of $i, just like your favorite editor's search & replace function would. So assume that $i is empty or, even more illustrative, assume that $i is a bunch of spaces! The shell will replace $i as follows:

if [     -ge 2 ] ; then ...

Now that variable substitutions are done, the shell proceeds with the comparison and.... fails because it cannot see anything intelligible to the left of -gt. However, quoting $i:

if [ "$i" -ge 2 ] ; then ...

becomes:

if [ "    " -ge 2 ] ; then ...

The shell now sees the double-quotes, and knows that you are actually comparing four blanks to 2 and will skip the if.

You also have the option of specifying a default value for $i if $i is blank, as follows:

if [ "${i:-0}" -ge 2 ] ; then ...

This will substitute the value 0 instead of $i is $i is undefined. I still maintain the quotes because, again, if $i is a bunch of blanks then it does not count as undefined, it will not be replaced with 0, and you will run into the problem once again.

Please read this when you have the time. The shell is treated like a black box by many, but it operates with very few and very simple rules - once you are aware of what those rules are (one of them being how variables work in the shell, as explained above) the shell will have no more secrets for you.

Cheers, V.

vladr
...I came looking for something _completely_ different, but your example of the default value is something I didn't know how to do and REALLY SHOULD HAVE! Your example has just saved me a LOT of hassle - and someday I really should get to some older code and "fix it." -smile- RT
Richard T
this worked for me, thanks!
Axarydax