Apple Developer Connection
Member Login Log In | Not a Member? Contact ADC

< Previous PageNext Page > Hide TOC

Other Comparisons

As mentioned in,“Shell Script Basics,” the shell scripting language contains basic equality testing without the use of the expr command. For example:

if [ 1 = 2 ] ; then
    echo "equal"
else
    echo "not equal"
fi

This code will work as expected. However, it isn't doing what you might initially think it is doing; this is performing a string comparison, not a numeric comparison. Thus the following code will not behave the way you would expect if you assumed it was comparing the numerical values:

if [ 1 = "01" ] ; then
    echo "equal"
else
    echo "not equal"
fi

It will print the words "not equal", as the strings "1" and "01" are not the same string.

!

Warning: Do not inadvertently perform a redirect instead of an inequality test. Take the following code for example:

if [ 2 > 3 ] ; then
    echo greater
fi
This will be true even though the comparison should be false. This is because no comparison is taking place. This is actually redirecting the output of the bracket command (an empty string) into a file called 3, which is probably not what you want.

The same thing occurs if you use the expr command without enclosing the less than or greater than operators in quotes.

This can also be a problem even when working with the expr command if your script takes user input. The expr command expects a number or symbol per argument. If you feed it something that isn't just a number or symbol, it will treat it as a string, and will perform string comparison instead of numeric comparison.

The following code demonstrates this in action:

expr '1' '+' '2'
expr ' 1' '+' '2'
expr '2' '<' '1'
expr ' 2' '<' '1'

The first line will print the number 3. The second line will give an error message. When doing addition, this is easy to detect. When doing comparisons, however, as shown in the following two lines, the results are more insidious. The number 2 is clearly greater than the number 1. In string comparison, however, a space sorts before any letter or number. Thus, the third line prints a 0, while the fourth line prints a 1. This is probably not what you want.

As with most things in shell scripting, there are many ways to solve this problem, depending on your needs. If you are only worried about spaces, and if the purpose for the comparison is to control shell execution, you can use the numeric evaluation routines built into test, as described in the test man page.

For example:

MYNUMBER=" 2" # Note this is a string, not a number.
# Force an integer comparison.
if [ "$MYNUMBER" -gt '1' ] ; then
    echo 'greater'
fi

However, while this works for trivial cases, there are a number of places where this is not sufficient. For example, this cannot be used if:

A common way to solve such problems is to process the arguments with a regular expression. For example, to strip any non-numeric characters from a number, you could do the following:

MYRAWNUMBER=" 2" # Note this is a string, not a number.
 
# Strip off any characters that aren't in the range of 0-9
MYNUMBER="$(echo "$MYRAWNUMBER" | sed 's/[^0-9]//g')"
 
expr "$MYNUMBER" '<' '1'

This would result in a comparison between the number 2 and the number 1, as expected.

For more information on regular expressions, see “Regular Expressions Unfettered.”



< Previous PageNext Page > Hide TOC


Last updated: 2008-04-08




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2007 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice