What is the difference between [and [[to Bash?


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?

[[ 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