aces are required after [
and before ]
.
[
is actually the name of a command, an alias fortest
. It’s not a special symbol, it’s just a command with an unusual name.$ help '[' [: [ arg... ] Evaluate conditional expression. This is a synonym for the "test" builtin, but the last argument must be a literal `]', to match the opening `['.
- Because it’s an ordinary command name and not a special character, a space is required after the
[
. If you omit the space and write[foo
the shell will search the$PATH
for a command named[foo
.$ [ foo = foo ] && echo true true $ [foo = foo] && echo true [foo: command not found
- For readability’s sake,
[
expects its last argument to be exactly]
. Being an ordinary command-line argument,]
must have a space before it. If there’s no space then the bracket will become the last character of the previous argument, and[
will complain about its last argument not being]
.$ [ foo = foo] bash: [: missing `]' $ [ foo = 'foo]' bash: [: missing `]'
[[
is a bash enhancement with more features than [
, namely saner handling of unquoted variable names. It requires the a space on both ends, same as [
. However [[
is in fact special shell syntax and is parsed differently. It’s not an “ordinary command” the way [
is.
||
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.- It has a wonderful
=~
operator for doing regular expression matches. With[
you might writeif [ "$answer" = y -o "$answer" = yes ]
With
[[
you can write this asif [[ $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. - 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.