Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting
PrevChapter 7. TestsNext

7.3. Comparison operators (binary)

integer comparison

-eq

is equal to

if [ "$a" -eq "$b" ]

-ne

is not equal to

if [ "$a" -ne "$b" ]

-gt

is greater than

if ["$a" -gt "$b" ]

-ge

is greater than or equal to

if [ "$a" -ge "$b" ]

-lt

is less than

if [ "$a" -lt "$b" ]

-le

is less than or equal to

if [ "$a" -le "$b" ]

<

is less than (within double parentheses)

(("$a" < "$b"))

<=

is less than or equal to (within double parentheses)

(("$a" <= "$b"))

>

is greater than (within double parentheses)

(("$a" > "$b"))

>=

is greater than or equal to (within double parentheses)

(("$a" >= "$b"))

string comparison

=

is equal to

if [ "$a" = "$b" ]

==

is equal to

if [ "$a" == "$b" ]

This is a synonym for =.

 1 [[ $a == z* ]] # true if $a starts with an "z" (pattern matching)
 2 [[ $a == "z*" ]] # true if $a is equal to z*
 3 
 4 [ $a == z* ] # file globbing and word splitting take place
 5 [ "$a" == "z*" ] # true if $a is equal to z*
 6 
 7 # Thanks, S.C.

!=

is not equal to

if [ "$a" != "$b" ]

This operator uses pattern matching within a [[ ... ]] construct.

<

is less than, in ASCII alphabetical order

if [[ "$a" < "$b" ]]

if [ "$a" \< "$b" ]

Note that the "<" needs to be escaped within a [ ] construct.

>

is greater than, in ASCII alphabetical order

if [[ "$a" > "$b" ]]

if [ "$a" \> "$b" ]

Note that the ">" needs to be escaped within a [ ] construct.

See Example 26-6 for an application of this comparison operator.

-z

string is "null", that is, has zero length

-n

string is not "null".

Caution

The -n test absolutely requires that the string be quoted within the test brackets. Using an unquoted string with ! -z, or even just the unquoted string alone within test brackets (see Example 7-6) normally works, however, this is an unsafe practice. Always quote a tested string. [1]


Example 7-5. arithmetic and string comparisons

 1 #!/bin/bash
 2 
 3 a=4
 4 b=5
 5 
 6 # Here "a" and "b" can be treated either as integers or strings.
 7 # There is some blurring between the arithmetic and string comparisons,
 8 #+ since Bash variables are not strongly typed.
 9 
 10 # Bash permits integer operations and comparisons on variables
 11 #+ whose value consists of all-integer characters.
 12 # Caution advised.
 13 
 14 echo
 15 
 16 if [ "$a" -ne "$b" ]
 17 then
 18 echo "$a is not equal to $b"
 19 echo "(arithmetic comparison)"
 20 fi
 21 
 22 echo
 23 
 24 if [ "$a" != "$b" ]
 25 then
 26 echo "$a is not equal to $b."
 27 echo "(string comparison)"
 28 # "4" != "5"
 29 # ASCII 52 != ASCII 53
 30 fi
 31 
 32 # In this particular instance, both "-ne" and "!=" work.
 33 
 34 echo
 35 
 36 exit 0


Example 7-6. testing whether a string is null

 1 #!/bin/bash
 2 # str-test.sh: Testing null strings and unquoted strings,
 3 # but not strings and sealing wax, not to mention cabbages and kings...
 4 
 5 # Using if [ ... ]
 6 
 7 
 8 # If a string has not been initialized, it has no defined value.
 9 # This state is called "null" (not the same as zero).
 10 
 11 if [ -n $string1 ] # $string1 has not been declared or initialized.
 12 then
 13 echo "String \"string1\" is not null."
 14 else 
 15 echo "String \"string1\" is null."
 16 fi 
 17 # Wrong result.
 18 # Shows $string1 as not null, although it was not initialized.
 19 
 20 
 21 echo
 22 
 23 
 24 # Lets try it again.
 25 
 26 if [ -n "$string1" ] # This time, $string1 is quoted.
 27 then
 28 echo "String \"string1\" is not null."
 29 else 
 30 echo "String \"string1\" is null."
 31 fi # Quote strings within test brackets!
 32 
 33 
 34 echo
 35 
 36 
 37 if [ $string1 ] # This time, $string1 stands naked.
 38 then
 39 echo "String \"string1\" is not null."
 40 else 
 41 echo "String \"string1\" is null."
 42 fi 
 43 # This works fine.
 44 # The [ ] test operator alone detects whether the string is null.
 45 # However it is good practice to quote it ("$string1").
 46 #
 47 # As Stephane Chazelas points out,
 48 # if [ $string 1 ] has one argument, "]"
 49 # if [ "$string 1" ] has two arguments, the empty "$string1" and "]" 
 50 
 51 
 52 
 53 echo
 54 
 55 
 56 
 57 string1=initialized
 58 
 59 if [ $string1 ] # Again, $string1 stands naked.
 60 then
 61 echo "String \"string1\" is not null."
 62 else 
 63 echo "String \"string1\" is null."
 64 fi 
 65 # Again, gives correct result.
 66 # Still, it is better to quote it ("$string1"), because...
 67 
 68 
 69 string1="a = b"
 70 
 71 if [ $string1 ] # Again, $string1 stands naked.
 72 then
 73 echo "String \"string1\" is not null."
 74 else 
 75 echo "String \"string1\" is null."
 76 fi 
 77 # Not quoting "$string1" now gives wrong result!
 78 
 79 exit 0
 80 # Also, thank you, Florian Wisser, for the "heads-up".


Example 7-7. zmost

 1 #!/bin/bash
 2 
 3 #View gzipped files with 'most'
 4 
 5 NOARGS=65
 6 NOTFOUND=66
 7 NOTGZIP=67
 8 
 9 if [ $# -eq 0 ] # same effect as: if [ -z "1ドル" ]
 10 # 1ドル can exist, but be empty: zmost "" arg2 arg3
 11 then
 12 echo "Usage: `basename 0ドル` filename" >&2
 13 # Error message to stderr.
 14 exit $NOARGS
 15 # Returns 65 as exit status of script (error code).
 16 fi 
 17 
 18 filename=1ドル
 19 
 20 if [ ! -f "$filename" ] # Quoting $filename allows for possible spaces.
 21 then
 22 echo "File $filename not found!" >&2
 23 # Error message to stderr.
 24 exit $NOTFOUND
 25 fi 
 26 
 27 if [ ${filename##*.} != "gz" ]
 28 # Using bracket in variable substitution.
 29 then
 30 echo "File 1ドル is not a gzipped file!"
 31 exit $NOTGZIP
 32 fi 
 33 
 34 zcat 1ドル | most
 35 
 36 # Uses the file viewer 'most' (similar to 'less').
 37 # Later versions of 'most' have file decompression capabilities.
 38 # May substitute 'more' or 'less', if desired.
 39 
 40 
 41 exit $? # Script returns exit status of pipe.
 42 # Actually "exit $?" unnecessary, as the script will, in any case,
 43 # return the exit status of the last command executed.

compound comparison

-a

logical and

exp1 -a exp2 returns true if both exp1 and exp2 are true.

-o

logical or

exp1 -o exp2 returns true if either exp1 or exp2 are true.

These are similar to the Bash comparison operators && and ||, used within double brackets.
 1 [[ condition1 && condition2 ]]
The -o and -a operators work with the test command or occur within single test brackets.
 1 if [ "$exp1" -a "$exp2" ]

Refer to Example 8-3 and Example 26-11 to see compound comparison operators in action.

Notes

[1]

As S.C. points out, in a compound test, even quoting the string variable might not suffice. [ -n "$string" -o "$a" = "$b" ] may cause an error with some versions of Bash if $string is empty. The safe way is to append an extra character to possibly empty variables, [ "x$string" != x -o "x$a" = "x$b" ] (the "x's" cancel out).


PrevHomeNext
File test operatorsUpNested if/then Condition Tests

AltStyle によって変換されたページ (->オリジナル) /