tags:

views:

68

answers:

3

I looked at bash man page and the [[ says it uses Conditional Expressions. Then I looked at Conditional Expressions section and it lists the same operators as test (and [).

So I wonder, what is the difference between [ and [[ in bash?

Thanks, Boda Cydo.

A: 

In bash, contrary to [, [[ prevents word splitting of variable values.

Xavier V.
+6  A: 

[[ is bash's improvement to the [ command. It has several enhancements that make it a better choice if you write scripts that target bash. My favorites are:

  1. It is a syntactical feature of the shell, so it has some special behavior that [ doesn't have. You no longer have to quote variables like mad because handles empty strings and strings with whitespace more intuitively. For example, with [ you have to write

    if [ -f "$FILE" ]
    

    to correctly handle empty strings or file names with spaces in them. With [[ the quotes are unnecessary:

    if [[ -f $FILE ]]
    
  2. Because it is a syntactical feature, it lets you use && and || operators for boolean tests and < and > for string comparisons. [ cannot do this because it is a regular command and &&, ||, <, and > are not passed to regular commands as command-line arguments.

  3. It has a wonderful =~ operator for doing regular expression matches. With [ you might write

    if [ "$ANSWER" = y -o "$ANSWER" = yes ]
    

    With [[ you can write this as

    if [[ $ANSWER =~ ^y(es)?$ ]]
    

    It even lets you access the captured groups which it stores in BASH_REMATCH. For instance, ${BASH_REMATCH[1]} would be "es" if you typed a full "yes" above.

  4. You get pattern matching aka globbing for free. Maybe you're less strict about how to type yes. Maybe you're okay if the user types y-anything. Got you covered:

    if [[ $ANSWER = y* ]]
    

Keep in mind that it is a bash extension, so if you are writing sh-compatible scripts then you need to stick with [. Make sure you have the #!/bin/bash shebang line for your script if you use double brackets.

See also

John Kugelman
Good, except [[ also exists in ksh and recent POSIX sh specifications.
Darron
+1  A: 
  • [ is the same as the test builtin, and works like the test binary (man test)
    • works about the same as [ in all the other sh-based shells in many UNIX-like environments
    • only supports a single condition. Multiple tests with the bash && and || operators must be in separate brackets.
    • doesn't natively support a 'not' operator. To invert a condition, use a ! outside the first bracket to use the shell's facility for inverting command return values.
    • == and != are literal string comparisons
  • [[ is a bash
    • is bash-specific, though others shells may have implemented similar constructs. Don't expect it in an old-school UNIX sh.
    • == and != apply bash pattern matching rules, see "Pattern Matching" in man bash
    • has a =~ regex match operator
    • allows use of parentheses and the !, &&, and || logical operators within the brackets to combine subexpressions

Aside from that, they're pretty similar -- most individual tests work identically between them, things only get interesting when you need to combine different tests with logical AND/OR/NOT operations.

Walter Mundt