69

I was trying to write a Bash script that uses an if statement.

if[$CHOICE -eq 1];

The script was giving me errors until I gave a space before and after [ and before ] as shown below:

if [ $CHOICE -eq 1 ];

My question here is, why is the space around the square brackets so important in Bash?

that other guy
  • 101,688
  • 11
  • 135
  • 166
Shash
  • 3,602
  • 7
  • 35
  • 56
  • 7
    The general syntax is `if command; then commands_if_exit_code_is_0; else commands_if_exit_code_is_nonzero; fi;`. *`command`* can be any command, and `[` is just one of them. – Benoit Mar 06 '12 at 09:43
  • Related: https://stackoverflow.com/questions/4977367/why-equal-to-operator-does-not-work-if-its-not-surrounded-by-space (you need spaces around the operator, too). – tripleee Oct 02 '17 at 04:37
  • See this related post: [Is double square brackets preferable over single square brackets in Bash?](https://stackoverflow.com/q/669452/6862601). – codeforester Aug 16 '18 at 02:28
  • https://stackoverflow.com/questions/2268104/command-not-found-error-in-bash-variable-assignment/2268117#2268117 – William Pursell Nov 05 '18 at 16:34
  • If `$CHOICE` is `"foo"`, you are attempting to run the command `["foo"`. – tripleee Jan 30 '20 at 18:20
  • In Bash, `[[` obeys the same requirements; you need spaces on both sides, and the command needs to end with `]]`. The doubled version is somewhat more versatile and robust; see the link by @codeforester above for a more nuanced discussion. – tripleee Mar 30 '21 at 04:24

4 Answers4

83

Once you grasp that [ is a command, a whole lot becomes clearer!

[ is another way to spell "test".

help [

However while they do exactly the same, test turns out to have a more detailed help page. Check

help test

...for more information.


Furthermore note that I'm using, by intention, help test and not man test. That's because test and [ are shell builtin commands nowadays. Their feature set might differ from /bin/test and /bin/[ from coreutils which are the commands described in the man pages.

hek2mgl
  • 133,888
  • 21
  • 210
  • 235
Johnsyweb
  • 121,480
  • 23
  • 172
  • 229
  • 6
    and originally, it was at `/usr/bin/[` and was a hardlink to `/usr/bin/test`, when invoked as `[` you should include a closing brace as last argument. Now it's a shell builtin. – Benoit Mar 06 '12 at 09:41
  • Note that they are not quite "exactly" the same. `[` requires that its last argument be `]`. – William Pursell Jul 15 '19 at 18:29
15

From another question:

A bit of history: this is because '[' was historically not a shell-built-in but a separate executable that received the expresson as arguments and returned a result. If you didn't surround the '[' with space, the shell would be searching $PATH for a different filename (and not find it) . – Andrew Medico Jun 24 '09 at 1:13

Community
  • 1
  • 1
Cameron
  • 1,595
  • 10
  • 12
9

[ is a command and $CHOICE should be an argument, but by doing [$CHOICE (without any space between [ and $CHOICE) you are trying to run a command named [$CHOICE. The syntax for command is:

command arguments separated with space
Jahid
  • 18,228
  • 8
  • 79
  • 95
2

[ is a test command. So it requires space.

Prince John Wesley
  • 58,850
  • 11
  • 80
  • 91