Historically, the test
command existed first (at least as far back to Unix Seventh Edition in 1979). It used the operators =
and !=
to compare strings, and -eq
, -ne
, -lt
, etc. to compare numbers. For example, test 0 = 00
is false, but test 0 -eq 00
is true. I don't know why this syntax was chosen, but it may have been to avoid using <
and >
, which the shell would have parsed as redirection operators. The test
command got another syntax a few years later: [ … ]
is equivalent to test …
.
The [[ … ]]
conditional syntax, inside which <
and >
can be used as operators without quoting, was added later, in ksh. It kept backward compatibility with [ … ]
, so it used the same operators, but added <
and >
to compare strings (for example, [[ 9 > 10 ]]
but [[ 9 -lt 10 ]]
). For more information, see using single or double bracket - bash
Arithmetic expressions also came later than the test
command, in the Korn shell, at some time in the 1980s. They followed the syntax of the C language, which was very popular in Unix circles. Thus they used C's operators: ==
for equality, <=
for less-or-equal, etc.
Unix Seventh Edition didn't have arithmetic expressions, but it did have the expr
command, which also implemented a C-like syntax for integer operations, including its comparison operators. In a shell script, the characters <
and >
had to be quoted to protect them from the shell, e.g. if expr 1 \< 2; …
is equivalent to if test 1 -lt 2; …
. The addition of arithmetic expressions to the shell made most uses of expr
obsolete, so it isn't well-known today.
In an sh script, you'd generally use arithmetic expressions to calculate an integer value, and [ … ]
to compare integers.
if [ "$((x + y))" -lt "$z" ]; then …
In a ksh, bash or zsh script, you can use ((…))
for both.
if ((x + y < z)); then …
The [[ … ]]
form is useful if you want to use conditionals involving things other than integers.
= != < <= > >=
compare strings.1 -eq 01
but1 != 01
and8 -lt 42
but8 > 42
– dave_thompson_085 Apr 24 '16 at 10:49