A co-worker claimed recently in a code review that the [[ ]]
construct is to be preferred over [ ]
in constructs like
if [ \"`id -nu`\" = \"$someuser\" ] ; then
echo \"I love you madly, $someuser\"
fi
He couldn\'t provide a rationale. Is there one?
[[
has fewer surprises and is generally safer to use. But it is not portable - POSIX doesn\'t specify what it does and only some shells support it (beside bash, I heard ksh supports it too). For example, you can do
[[ -e $b ]]
to test whether a file exists. But with [
, you have to quote $b
, because it splits the argument and expands things like \"a*\"
(where [[
takes it literally). That has also to do with how [
can be an external program and receives its argument just normally like every other program (although it can also be a builtin, but then it still has not this special handling).
[[
also has some other nice features, like regular expression matching with =~
along with operators like they are known in C-like languages. Here is a good page about it: What is the difference between test, [
and [[
? and Bash Tests
[[ ]]
has more features - I suggest you take a look at the Advanced Bash Scripting Guide for more info, specifically the extended test command section in Chapter 7. Tests.
Incidentally, as the guide notes, [[ ]]
was introduced in ksh88 (the 1988 version of the Korn shell).
Behavior differences
First, let\'s analyse the behavior differences between both. Tested in Bash 4.3.11.
Recommendation
I prefer to always use []
.
There are POSIX equivalents for every [[ ]]
construct I\'ve seen.
If you use [[ ]]
you:
- lose portability
- force the reader to learn the intricacies of another bash extension.
[
is just a regular command with a weird name, no special semantics are involved.
From Which comparator, test, bracket, or double bracket, is fastest? (http://bashcurescancer.com)
The double bracket is a “compound
command” where as test and the single
bracket are shell built-ins (and in
actuality are the same command). Thus,
the single bracket and double bracket
execute different code.
The test and single bracket are the
most portable as they exist as
separate and external commands.
However, if your using any remotely
modern version of BASH, the double
bracket is supported.
A typical situation where you cannot use [[ is in an autotools configure.ac script, there brackets has a special and different meaning, so you will have to use test
instead of [ or [[ -- Note that test and [ are the same program.
In a nutshell, [[ is better because it doesn\'t fork another process. No brackets or a single bracket is slower than a double bracket because it forks another process.
[[ ]] double brackets are unsuported under certain version of SunOS and totally unsuported inside function declarations by :
GNU bash, version 2.02.0(1)-release (sparc-sun-solaris2.6)