4

In a bash script, I'm willing to check if a parameter has a boolean value ("true" or "false").
I'm attempting this in two scripts in two different ways, both failing.
I've checked many Stack Exchange hints, and I believe doing what I should, but it isn't the case.

if [ "$2" != "true" ] -a [ "$2" != "false" ]; then
  echo "Indiquez si Geoserver est en installation initiale (false) ou update (true)" >&2;
  exit 1;
fi

fails with the message Geoserver.sh: 12: [: true: unexpected operator

if [[ "$3" != "true" && "$3" != "false" ]]; then
  echo "Indiquez si Kafka est en installation initiale (false) ou update (true)" >&2;
  exit 1;
fi

fails with Kafka.sh: 18: [[: not found

  • 1
    Try something like: if [ "$2"z != "true" ] -a [ "$2" != "false"z ]; then. ANd usually in if are user && and || for AND and OR. And the reason for the error for me is $2 is empty – Romeo Ninov Jun 02 '23 at 05:02
  • 10
    Also mention how you run your script. It seems as if you are running it with sh, not with bash. – Kusalananda Jun 02 '23 at 05:05
  • 1
    You're both right! My script was called by a sh instead of a bash. – Marc Le Bihan Jun 02 '23 at 05:29
  • I always thought [ "a" != "a" -a "b" != "b" ] is the way to combine tests with -a based on man [. The alternate to [ EXPR ], test EXPR can also be used as well, you can check from the command line: test "a" = "a" -a "b" = "b"; echo $? – chexum Jun 02 '23 at 06:17
  • 3
    @chexum Both -a and -o are marked obsolete in the POSIX standard (see the "APPLICATION USAGE" section here). It's too difficult to write unambiguous code with them. – Kusalananda Jun 02 '23 at 06:22
  • @Kusalananda ouch, thanks - this only shows my age, but obsoleting these sounds to me so unacceptable as obsoleting fgrep/egrep :) – chexum Jun 02 '23 at 06:26
  • 2
    @chexum Sometimes it's just better to accept change :-) And the preferred new way of doing this looks easier to read, IMHO. As for fgrep and egrep, adding standard options to grep did sound better than having a proliferation of utilities that do essentially the same thing, but I agree that muscle memory is difficult to re-train. – Kusalananda Jun 02 '23 at 06:34

2 Answers2

12

The standard way would be

[ "$3" != "true" ] && [ "$3" != "false" ]

That is to run two [ commands each performing a single test and chained with the shell's && operator.

[[...]] is special non-standard shell syntax from ksh, supported by many feature-rich shells, and it does (usually) support && inside the brackets. It should be available in bash as long as bash was not built with --disable-cond-command, but the wording of your error message suggests you're rather using the dash shell. With a bash built with --disable-cond-command, the errors would rather be: Geoserver.sh: 12: [: too many arguments and Kafka.sh: 18: [[: command not found respectively.

-a would be supported within [ for backward compatibility, as in [ "$2" != "true" -a "$2" != "false" ], but is deprecated and broken by design and (like its -o counterpart for or) should not be used.

It's complicated, see e.g.

ilkkachu
  • 138,973
8

Both errors suggest you are not using bash at all, but some lesser featured shell, such as dash for example.

Furthermore, in your first example, you have incorrectly implemented an "and" clause.

This is what I think you were going for, and should work if you actually were to use bash:

if [ "$2" != "true" -a "$2" != "false" ]; then

Although the preferred method tends to be this more portable option:

if [ "$2" != "true" ] && [ "$2" != "false" ]; then

The error for the second example again suggests you are not using a shell that supports [[ ]] notation, if you change to the above [ ] && [ ] style notation you may have more success.

bxm
  • 4,855
  • 1
    The error messages indeed match what Dash would print – ilkkachu Jun 02 '23 at 13:56
  • 1
    -a is broken by design and deprecated and should NOT be used. It doesn't work reliably, in bash included (especially in bash). bash -c '[ "$2" != "true" -a "$2" != "false" ]' bash x '!' for instance fails with bash: line 1: [: too many arguments – Stéphane Chazelas Jun 03 '23 at 08:18