8

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?

2 Answers 2

12

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
1
  • 1
    Your last two lines of the post nails the answer. Thanks.
    – bagavadhar
    Commented Apr 13, 2013 at 4:02
4

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).

2
  • One thing that to note that [[, [, and (( )) can all be used outside of conditionals (although it only makes sense for (( ))).
    – jordanm
    Commented Apr 13, 2013 at 2:52
  • 1
    Well, you can also use [[ 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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .