-2
if [ $inst != "GPS" && $inst != "USRP" && $inst != "GCSM" &&  $inst != "EFMS" && $inst != "instAR" && $inst != "CRF" && $inst != "DBOR" && $inst != "PAL"     &&  $inst != "GRDB" && $inst != "GIOM" && $inst != "FA" && $inst != "WS" ]
then
    help
fi

Error message:

30: [: missing `]'

What does this mean and how do I fix it?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578

2 Answers2

2

Bash's error messages can be cryptic. Why does it say there's a missing ] when you have one at the end of the line? I don't blame you for finding that confusing.

Shell Check is a great tool for linting shell scripts, often producing much better diagnostics with links to detailed writeups. For your script it reports:

SC2107 (error): Instead of [ a && b ], use [ a ] && [ b ].

The full explanation for SC2107 reads:

Instead of [ a && b ], use [ a ] && [ b ].

Problematic code:

[ "$1" = "-v" && -z "$2" ]

Correct code:

[ "$1" = "-v" ] && [ -z "$2" ]

Rationale:

&& can not be used in a [ .. ] test expression. Instead, make two [ .. ] expressions and put the && between them.

Exceptions:

None.

Related resources:


An alternative way to write the check is to use a case block.

case "$inst" in
    GPS|USRP|GCSM|EFMS|instAR|CRF|DBOR|PAL|GRDB|GIOM|FA|WS)
        # match
        ;;

    *)
        # no match
        help
        ;;
esac

Or you could use =~ to match against a regular expression. Note that this requires the use of double square brackets [[ as well, and therefore requires a #!/bin/bash shebang. It won't work in a plain #!/bin/sh script.

#!/bin/bash

if ! [[ $inst =~ ^(GPS|USRP|GCSM|EFMS|instAR|CRF|DBOR|PAL|GRDB|GIOM|FA|WS)$ ]]
    help
fi
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • I thought SO encouraged, nay demanded, some effort on the part of the poster. –  Feb 10 '22 at 13:17
  • @Roadowl OP wrote some code and didn't understand why it was wrong. That's a far cry from providing a description of the program to write with no code whatsoever. – chepner Feb 10 '22 at 16:33
0

The syntax you are trying to use is quite unwieldy anyway. May I suggest you switch to a case statement instead?

case $inst in 
  GPS|USRP|GCSM|EFMS|instAR|CRF|DBOR|PAL|GRDB|GIOM|FA|WS)
    ;;
  *)
    help
  ;;
esac

The punctuation-heavy syntax of this statement may be jarring at first, but you should find that it is a lot more robust and versatile than the clunky if.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • @triplee don't you need to be using `[[...]]` instead of `[...]` to be able to use `&&` instead of `-a`? I don;t really remember right now and am too lazy to look it up or try it. – Ed Morton Feb 10 '22 at 13:35
  • It's not a shell syntax error, it's a `test`/`[` error. The `&&` separates the simple command `[ $inst != "GPS"` from another command list, and `[` is noting that it did not receive its mandatory final argument `]`. – chepner Feb 10 '22 at 16:36