When are square brackets required in a Bash if statement?
Usually, I use square brackets in the if statement:
if [ "$name" = 'Bob' ]; then ...
But, when I check if grep
succeeded I don't use the square brackets:
if grep -q "$text" $file ; then ...
When are the square brackets necessary in the if
statement?
The square brackets are a synonym for the test
command. An if
statement checks the exit status of a command in order to decide which branch to take. grep -q "$text"
is a command, but "$name" = 'Bob'
is not--it's just an expression. test
is a command, which takes an expression and evaluates it:
if test "$name" = 'Bob'; then ...
Since square brackets are a synonym for the test
command, you can then rewrite it as your original statement:
if [ "$name" = 'Bob' ]; then ...
[
is actually a command, equivalent (almost, see below) to the test
command. It's not part of the shell syntax. (Both [
and test
, depending on the shell, are often built-in commands as well, but that doesn't affect their behavior, except perhaps for performance.)
An if
statement executes a command and executes the then
part if the command succeeds, or the else
part (if any) if it fails. (A command succeeds if it exits with a status ($?
) of 0, fails if it exits with a non-zero status.)
In
if [ "$name" = 'Bob' ]; then ...
the command is
[ "$name" = 'Bob' ]
(You could execute that same command directly, without the if
.)
In
if grep -q "$text" $file ; then ...
the command is
grep -q "$text" $file
man [
or man test
for more information.
FOOTNOTE: Well, the [
command is almost equivalent to the test
command. The difference is that [
requires ]
as its last argument, and test
does not -- and in fact doesn't allow it (more precisely, test
doesn't treat a ]
argument specially; for example it could be a valid file name). (It didn't have to be implemented that way, but a [
without a matching ]
would have made a lot of people very very nervous.)
The best way to think of the [ ... ]
syntax, is to consider [
to be a program - which it is!
Check this out:
~ $ ls /usr/bin/\[
/usr/bin/[
on the other hand, you're probably not using that version of it since bash
also provides [
as a shell built-in.
Anyway, to answer your question: What if
does is run the command you give it and see it the return value is 0
or not. You use [
to do other, more interesting comparisons such as string comparisons. See man [
and man bash
.