I see that
if cmd
then
echo Hi
fi
works differently from
if [[ $(cmd) ]]
then
echo Hi
fi
So what happens when there is a [[ and when there is not?
In the shell [
is an alias for the test command. It is the command. The [[
is a feature of some shells that is only slightly different. In bash it is a keyword, rather than a command, but functions like a command.
You can think of it this way: you are running [[
and providing the output of "$(cmd)" as arguments to that command. if
then checks the return status of [[
. When no operators are given to [[
, -n
is implied.
-n string
True if the length of string is non-zero.
For your examples:
if cmd # check the return status of cmd
if [[ $(cmd) ]] # check if cmd has any output
An if expr
statement (without brackets) checks the return status of expr
after it's evaluated as a bash command. Upon success, it is treated as a true
value.
On the other hand, if [[ expr ]]
with double square brackets is a bash
-specific keyword that can handle its own set of options, such as -f /path/to/file
to test for file existence, or even handle variable tests such as $a == $b
. Within these brackets, you have to explicitly tell it to evaluate some expression as a set of bash commands with if [[ $(cmds) ]]
. Otherwise, it will treat anything there as a special expression and will be parsed differently.
There's also the if [ expr ]
construct, which is generally an alias (or, in some cases, an approximative implementation of) if test expr
. If the test
command has an option available to use, then you can also use it between single brackets.
For more fun, there's the if ((expr))
construct, which is best when dealing with numbers, since everything inside is evaluated as an arithmetic expression. This is also a keyword, like the double brackets.
Basically, if expr
and if [ expr ]
are portable (i.e. all shells can handle them, and handle them pretty much identically) and if [[ expr ]]
and if (( expr ))
are implementation-specific, i.e. they are keywords whose evaluation depend highly on the shell you're using them in (and if you're not using something like bash
, zsh
, or ksh
, they might not even exist).
[[
, [
, and (( ))
can all be used outside of conditionals (although it only makes sense for (( ))
).
[[
outside conditionals for more succinct syntax, like [[ expr ]] && expr_is_true_cmds || expr_is_false_cmds
. But that's not as readable, ofc.
Commented
Apr 13, 2013 at 2:56