Compare integer in bash, unary operator expected

LinuxBashShell

Linux Problem Overview


The following code gives

> [: -ge: unary operator expected

when

i=0

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

why?

Linux Solutions


Solution 1 - Linux

Your problem arises from the fact that $i has a 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.

Solution 2 - Linux

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

Solution 3 - Linux

I need to add my 5 cents. I see everybody use [ or [[, but it worth to mention that they are not part of if syntax.

For arithmetic comparisons, use ((...)) instead.

> ((...)) is an arithmetic command, which returns an exit status of 0 if > the expression is nonzero, or 1 if the expression is zero. Also used > as a synonym for "let", if side effects (assignments) are needed. > > See: ArithmeticExpression

Solution 4 - Linux

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFilip EkbergView Question on Stackoverflow
Solution 1 - LinuxvladrView Answer on Stackoverflow
Solution 2 - LinuxstarblueView Answer on Stackoverflow
Solution 3 - LinuxRoman NewazaView Answer on Stackoverflow
Solution 4 - LinuxFernando MiguélezView Answer on Stackoverflow