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

7
  • 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 Commented Jun 2, 2023 at 5:02
  • 10
    Also mention how you run your script. It seems as if you are running it with sh, not with bash.
    – Kusalananda
    Commented Jun 2, 2023 at 5:05
  • 1
    You're both right! My script was called by a sh instead of a bash. Commented Jun 2, 2023 at 5:29
  • 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
    Commented Jun 2, 2023 at 6:22
  • 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
    Commented Jun 2, 2023 at 6:34

2 Answers 2

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.

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.

2
  • 1
    The error messages indeed match what Dash would print
    – ilkkachu
    Commented Jun 2, 2023 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 Commented Jun 3, 2023 at 8:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .