2

I'm trying to write a case statement where the variable argument does not match a test expression.

In other words:

case $db in
      [Some Code Here])
          echo "Not a valid database type"
          exit 1
          ;;
esac

$db should only have the values "mssql" or "postgres" otherwise the script should exit.

How do I do this in a case statement?

1 Answer 1

4

You'd do (and that would even be standard sh syntax, so you wouldn't even need bash to be installed):

case $db in
  (mssql | postgres) ;; # OK
  (*)
    echo >&2 "Not a valid database type"
    exit 1
    ;;
esac

In ksh or in bash after shopt -s extglob (or zsh after set -o kshglob though zsh has its own negation and alternation operators which you'd likely prefer there), you could do:

case $db in
  (!(mssql|postgres))
    echo >&2 "Not a valid database type"
    exit 1
    ;;
esac

But more generally, for input validation it's better to match on what you allow rather than trying to match all the things that you don't want to allow as doing the latter reliably if often difficult in the general case and comes with higher risk (safer to reject too much than not enough).

Note that in ksh88 and older versions of ksh93.

case $db in
  (@(mssql|postgres)) ;; # OK
  (*)
    echo >&2 "Not a valid database type"
    exit 1
    ;;
esac

That is using the @(a|b) alternation pattern operator rather than two patterns separated with | in the case statement) would not reject a $db that contains @(mssql|postgres) literally (a misfeature inherited from the Bourne shell).

You must log in to answer this question.

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