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?
CodePudding user response:
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
CodePudding user response:
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
.