1

I am not sure about this comparison i am doing:

   if [ "$exit_status" -eq 0 ];then
   #some statements
   fi

is this correct way of comparing numbers or quotes make the variable exit_status a string to be compared with 0.I don't know if this could fail in some scenario.

1
  • It is correct but if you are using Bash you should use ((...)). It 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 Arithmetic Expression. Apr 28, 2013 at 14:51

3 Answers 3

4

Yes, it is correct.

Quotes in shells are for different purpose than in other languages. See this answer for more details.

In shell, quotes are used to prevent the shell to treat some characters specially and to prevent some operations that the shell would otherwise perform upon some types of expansion (like in this case variable expansion).

Typically, in this case, you want "$exit_status" to be expanded to one argument to the [ command that is the content of that varaible, so you need the quotes.

2

[ "$exit_status" -eq 0 ] is correct if $exit_status only contains digits, and you could just as well remove the quotes (as long as IFS doesn't contain digits).

If x is empty or unset, [ "$x" -eq 6 ] results in an error but [[ "$x" -eq 6 ]] doesn't:

$ x=; [ "$x" -eq 6 ]
-bash: [: : integer expression expected
$ unset x; [ "$x" -eq 6 ]
-bash: [: : integer expression expected
$ x=; [[ "$x" -eq 6 ]]
$ unset x; [[ "$x" -eq 6 ]]
$ 

Arithmetic operators strip whitespace:

$ [ '6 ' -eq $'\n\t6' ]; echo $?
0

Inside [[ the operands of arithmetic operators are arithmetic expressions, so for example [[ 4 -eq 2+2 ]] is true. Numbers that start with 0 are treated as octal numbers:

$ [[ 010 -eq 8 ]]; echo $?
0
$ [ 010 -eq 8 ]; echo $?
1

I often use = / == even for comparing integers. = and == are equivalent in bash inside both [[ and [. == and [[ are not defined by POSIX.

Word splitting and pathname expansion are not performed inside [[. [[ $x = $y ]] treats y as a pattern but [[ $x = "$y" ]] treats y literally:

$ x=44; y='4*'
$ [[ $x = $y ]]; echo $?
0
$ [[ $x = "$y" ]]; echo $?
1
1
  • 1
    More precisely, [[...]]'s -eq compares two arithmetic expressions, while ['s compares decimal integer constants only (but you can do [ "$((6+6))" -eq "$((0xc))" ] with the standard syntax for [[ 6+6 -eq 0xc ]]). While you're at using non-standard ksh extensions, it's better to do (( exp1 == exp2 )) to do arithmetic comparison. Note that [[ "1 + 1" -eq "4 - 2" ]] is not equivalent to [[ 1 + 1 -eq 4 - 2 ]] (which would be a syntax error), and [[ $x*2 -eq $y*3 ]] is not the same as [[ x*2 -eq y*3 ]] (for instance in cases where $x is 1+2). Apr 30, 2013 at 11:31
-1

Quoting numbers is of little use though. If the parameter value is a number then the quotes don't change anything and if it is not then the if is going to fail anyway. OK, not in every case:

exit_status="a = a -o 0"; [ "$exit_status" -eq 0 ] # returns false
exit_status="a = a -o 0"; [ $exit_status -eq 0 ] # returns true

This is due to [ being a bash builtin but nonetheless a simple command whereas [[ is a compound command that changes command line parsing.

1
  • 2
    You've got it backward. It's not quoting numbers that is of little use. Not quoting a variable (even if you know for sure contains only decimal digits) still asks the shell to perform word splitting, filename generation and empty removal on it, and it would still be a problem if $IFS does happen to contain digits. Quoting variables should always be the default. Only remove the quotes if you have a good reason to, like in the rare cases where you do need word splitting or filename generation. Apr 24, 2013 at 13:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .