Examples of 'if' and test in bash
I have a hard time keeping the various syntaxes used for testing variales
used in shell scripting. You'd think that with all the books available
on shell scripting, ONE of them would have a chapter or appendix that just
listed a bunch of examples of when to use [[]] instead of [] or (()), and so
on. If there is such a book, I haven't found it. So, this page is my own
little set of examples so that I can quickly lookup what syntax to use
depending on what exactly I'm testing.
Some preface is in order:
- [] and [[]] are used for testing strings
- = is used for string comparison
- -eq, -gt, -lt, etc. are used for integer comparison
- () is used for grouping, to separate parts
- $(()) is used for arithmetic tests
The syntax used in a script would be
if [[ condition ]]; then
but I've left
out the 'if', the semicolon and the 'then' just for brevity. For each example
given below, if the example works for a shell, that shell is listed in
green and if it doesn't work for a shell, the shell
name is showin in red.
String comparison
Summary: Use double brackets [[]] and single equal sign =
For the examples below, we'll define x=hello4you. Let's start with string
comparison which uses = and ==. (This always seems backwards to me, to use math
signs for strings and letters like -eq for number comparison.)
[[ $x = hello4you ]]
bash ksh
This is the preferred syntax and is shown in the O'Reilly books.
Negative: [[ $x != hello4you ]]
[ $x = hello4you ]
bash ksh
This works in bash and ksh and is the syntax I've seen in many scripts--grep for
'if' in /etc/init.d/ or /sbin/init.d/ and you'll see most scripts use single
brackets. But since it won't handle wildcards (see below) and it's not the syntax
given in books, I'm not sure why its use is so common.
[[ $x == hello4you ]]
bash ksh
This works in bash but fails in ksh. ksh doesn't like the == although the QA
book shows this exact syntax as a working example for ksh.
Using single or double brackets makes no difference, nor does quoting.
It does seem odd that = works
and == does not since we're evaluating $x, not setting it.
Wildcards
[[ $x = h*you ]]
bash ksh
This works in bash and ksh; wildcards REQUIRE [[]], and fail with [].
The bottom line is use double bracket and single equal sign and
you'll be okay in all cases. Wildcards
don't work inside quotes; for example, if x="John Brown", then
[[ $x = John* ]]
will work, but
[[ $x = "John*" ]] will not.
Negative: [[ $x != *youX ]]
The negative example will be true because of the X at the end of the string which
means $x does not match it.
Number comparison (not calculation)
Summary: Use (()) and == for simple true/false test
For these examples, we set x=57. O'Reilly says [[]] will also work, but that (())
is "considerably more efficient", so both are shown here.
(( $x == 57 ))
bash ksh
This works in bash and ksh. Note the use of the double-equal sign. This is probably
where confusion is created as to whether single or double equals should be used, since
[[]] uses single and (()) uses double on ksh. Also note that we're not doing any
calculations here; for that the $(()) must be used (see below). The
difference is that (()) just produces a result code, 0 if true, 1 if not, whereas
$(()) produces a 'textual result' (the answer). O'Reilly calls these "arithmetic conditionals".
Negative: (( $x != 58 ))
[[ $x -eq 57 ]]
bash ksh
This works in bash and ksh. It produces just a result code of 0 or 1, similar
to (()). O'Reilly calls these "integer conditionals".
Negative: [[ $x -ne 58 ]]
[ $x = 57 ]
bash ksh
This works in bash and ksh but 57 is being treated as a string not a number,
which probably isn't what you want.
[ $x -gt 47 ]
bash ksh
Single brackets works in bash and ksh. This is just an example showing how
numbers can be compared.
File tests
For these examples, we set x to a valid file name.
02/28/2006