Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

This question already has an answer here:

The zsh man page, in its section on test (aka [), explicitly advises against using it at all, and urges readers to use [[ whenever possible.

The relevant section states:

The command attempts to implement POSIX and its extensions where these are specified. Unfortunately there are intrinsic ambiguities in the syntax; in particular there is no distinction between test operators and strings that resemble them. The standard attempts to resolve these for small numbers of arguments (up to four); for five or more arguments compatibility cannot be relied on. Users are urged wherever possible to use the '[[' test syntax which does not have these ambiguities.

I think I've come across similar advice for bash, but as I scan over the bash man page I can't find any "official" recommendation there on which form ([ or [[) to use. (Maybe I missed it?)

Is there any reason, other than backward compatibility with "older shells", for using [ in a bash script? Or to put it differently, does bash keep [ along with [[ for reasons other than backward compatibility?

share|improve this question

marked as duplicate by Stéphane Chazelas, Gilles, manatwork, maxmackie, kjo Mar 7 '13 at 14:32

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
    
Dang, usually the stackexchange interface saves me from posting duplicates, but this time it didn't: it showed exactly 0 suggestions for similar questions, which is pretty unusual, and maybe for this reason made me a bit over-confident... Sorry about that. –  kjo Mar 7 '13 at 13:55

2 Answers 2

up vote 3 down vote accepted

The reason to prefer [ over [[ if sufficient is that [ is more stable between the different bash versions.

See man bash:

compat31

If set, bash changes its behavior to that of version 3.1 with respect to quoted arguments to the [[ conditional command's =~ operator.

compat32

If set, bash changes its behavior to that of version 3.2 with respect to locale-specific string comparison when using the [[ conditional command's < and > operators. Bash versions prior to bash-4.1 use ASCII collation and strcmp(3); bash-4.1 and later use the current locale's collation sequence and strcoll(3).

compat40

If set, bash changes its behavior to that of version 4.0 with respect to locale-specific string comparison when using the [[ conditional command's < and > operators (see previous item) and the effect of interrupting a command list.

Maybe it is also a little bit more common to users with ksh background.

Note about performance

'[[' is quicker as '['

  • For a singular invocation the speed difference has no commensurable impact, and your should prefer the '[' builtin.
  • If you it inside a bigger loop construct, you may think of replace '[' with '[['

For a measurement you may use the following compare script

let upperBound=$1
echo "check [,  ${upperBound} iterations"
let i=0
time while [ $i -lt ${upperBound} ] ; do let i++ ; done

echo; echo;
echo "check [[, ${upperBound} iterations"
let i=0
time while [[ $i < ${upperBound} ]] ; do let i++ ; done

Result of compare script

check [, 1000 iterations

real 0m0.031s
user 0m0.028s
sys 0m0.004s

check [[, 1000 iterations

real 0m0.000s
user 0m0.000s
sys 0m0.000s

share|improve this answer
1  
+= And the reason to not use it — it's slower then (again) built-in version [[. –  poige Mar 7 '13 at 12:07

There are some subtle differences though:

#!/bin/bash

eg=whatever

if [ $eg == what* ]; then   # file glob test
    echo '[]'
fi

if [[ $eg == what* ]]; then   # pattern match test
    echo "[[]]"
fi      

Unless there is a file called "what[something]" in the current directory, the first test will not pass.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.