13

Possible Duplicate:
bash: double or single bracket, parentheses, curly braces

Looking at the rc.d cron script in archlinux:

#!/bin/bash
. /etc/rc.conf
. /etc/rc.d/functions

name=crond
. /etc/conf.d/crond
PID=$(pidof -o %PPID /usr/sbin/crond)

case "$1" in
start)
    stat_busy "Starting $name daemon"
    [[ -z "$PID" ]] && /usr/sbin/crond $CRONDARGS &>/dev/null \
    && { add_daemon $name; stat_done; } \
    || { stat_fail; exit 1; }
    ;;

While I can figure out most of the syntax, what the heck does this do:

 [[ -z "$PID" ]]

I saw that also written as:

 [ -z "$PID" ]

In reference I found that [] is used in if-statements, but I see none here. Any help is much appreciated. Thanks!

Community
  • 1
  • 1
Andriy Drozdyuk
  • 58,435
  • 50
  • 171
  • 272

3 Answers3

14

The opening bracket ([) is an alias for the test command which performs all the tests and returns 0 for true or something else for false. The "if" reacts only to the return value of the test command. The closing bracket tells test where the expression ends. The double brackets ([[) are a bash built in and can replace the external call to test.

Mithrandir
  • 24,869
  • 6
  • 50
  • 66
8

The single brackets emulate /usr/bin/test , an old Unix utility. They do what you ask for, but not what you want. The double brackets are improvement, peculiar to Bash.

http://tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS

There exists a dedicated command called [ (left bracket special character). It is a synonym for test, and a builtin for efficiency reasons. This command considers its arguments as comparison expressions or file tests and returns an exit status corresponding to the result of the comparison (0 for true, 1 for false).

With version 2.02, Bash introduced the [[ ... ]] extended test command, which performs comparisons in a manner more familiar to programmers from other languages. Note that [[ is a keyword, not a command.

No filename expansion or word splitting takes place between [[ and ]], but there is parameter expansion and command substitution.

Using the [[ ... ]] test construct, rather than [ ... ] can prevent many logic errors in scripts. For example, the &&, ||, <, and > operators work within a [[ ]] test, despite giving an error within a [ ] construct.

Colonel Panic
  • 132,665
  • 89
  • 401
  • 465
  • +1 for "do what you ask for, but not what you want" – chepner Aug 03 '12 at 13:38
  • i don't want my computer to guess what i want and still insist on it doing exactly as i say. :-) – Mithrandir Aug 03 '12 at 13:41
  • @Mithrandir ...but if it interprets what you say in a way unlikely to be what you actually want, that's a problem -- and that's what `test` does, whereas `[[ ]]` is not only predictable, but also more likely to be correct. – Charles Duffy Aug 03 '12 at 13:42
  • 2
    An excellent explanation, though the ABS is otherwise full of errors (we're constantly helping people who've made the mistake of following its advice in #bash), and this could potentially lead people there -- perhaps a "for more information see" link could be added to http://mywiki.wooledge.org/BashGuide/TestsAndConditionals ? – Charles Duffy Aug 03 '12 at 13:43
  • @CharlesDuffy of course your right, the [[ is much easier to use, but test has done a great job for me (for far more years than a care to admit), but one has to use it with care to prevent unexpected behavior. – Mithrandir Aug 03 '12 at 13:47
  • Double brackets are also supported in ksh and zsh so they're not peculiar to Bash. – Dennis Williamson Aug 03 '12 at 19:19
0

From this manual:

Brackets to return a binary result of expression: [[ ]]

[[ expression ]]

Return a status of 0 or 1 depending on the evaluation of the conditional expression. Word splitting and filename expansion are not performed on the words between the [[' and]]'; tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal are performed.

The && and || commands do not execute expression2 if the value of expression1 is sufficient to determine the return value of the entire conditional expression.

Daniel O'Hara
  • 13,307
  • 3
  • 46
  • 68