1

I am learning Korn shell which is based on Bourne shell. Below is my really simple code.

read ab
if [ $ab = "a" || $ab = "A" ] ; then
    echo hi
fi

For some reason || operator is giving me the error:

[: missing `]'
a: command not found
codeforester
  • 39,467
  • 16
  • 112
  • 140
Mint.K
  • 849
  • 1
  • 11
  • 27
  • 2
    The `||` is interpreted by the shell, not by the `[` command (yes, `[` is a command). So `[` is invoked with arguments `$ab = "a"`, and it complains about the missing `]`. You could use `-o`, which is the "or" command for `[`, but the method in @codeforester is probably a better way to do it. – Keith Thompson Feb 26 '17 at 01:23
  • @KeithThompson - I have come to understand that `-o` has been deprecated in more recent version of Bash. Not sure about ksh though. – codeforester Feb 26 '17 at 01:28
  • 2
    @codeforester, it's actually the POSIX spec that marked it obsolescent, not any particular shell. – Charles Duffy Feb 26 '17 at 01:49
  • These problems really do become less common if you use `test`: `if test "$ab" = a || test "$ab" = A; then ...` is less error prone. – William Pursell Feb 26 '17 at 05:08
  • 1
    Your use of quotes is exactly backwards. There is no need to quote the string `a`, but there is good reason to quote `"$ab"` – William Pursell Feb 26 '17 at 05:09

2 Answers2

3

The correct way to write your if condition is:

read ab
if [ "$ab" = "a" ] || [ "$ab" = "A" ]; then
  echo hi
fi

With [ ... ], it is essential to put the variables in double quotes. Otherwise, shell will fail with a syntax error if the variables expand to nothing or if their expansion contains spaces.


See also:

Community
  • 1
  • 1
codeforester
  • 39,467
  • 16
  • 112
  • 140
  • I am using ${ab}, do you still recommend using double quotes? – Mint.K Feb 26 '17 at 01:22
  • 1
    @Mint.K: Yes. `${ab}` will still expand to two or more words if it contains white space. – Keith Thompson Feb 26 '17 at 01:23
  • @Mint.K, `${ab}` is no different at all from `$ab` unless you're performing a concatenation operation with a string that starts with a character that's legal as part of a shell variable name (ie. `${ab}_foo`). – Charles Duffy Feb 26 '17 at 01:49
1

If you use ksh or a modern bash you can use the non-standard [[ ... ]] instead of [ ... ].

This has two benefits:

  1. You can use || inside [[ ... ]]
  2. Variable expansions do not need quotes.

This makes it safe and shorter to write

[[ $ab = a || $ab = A ]]
Henk Langeveld
  • 8,088
  • 1
  • 43
  • 57