Case statements in shell script

Josh Sherman
2 min read
Command-line Interface Shell Script

While I do love the command-line, and will throw shell script at most problems if it’s the right tool for the job, it’s actually fairly rare that I write case statements.

Generally speaking, my shell scripts will usually interrogate a variable or two, never too crazy or anything.

With that, recently I was writing a shell script for work and given the number of conditionals I needed, it made sense to venture down the path of a case statement.

If you’re familiar with switch statements in other languages, the case statement is the same deal, but with slightly different syntax. Instead of opening the statement with switch we’ll be using case and each of our patterns to match will be inside of that (without the familiar case prefix on each one).

Similar to how if statements are finished with a fi (if backwards), case statements do the same, finishing up with esac:

#!/usr/bin/env bash

variable="foo"

case variable in
  # This is where our patterns to match will go...
esac

As mentioned, the patterns to match will be listed in between case and esac, but before we list those out, let’s add a catchall (similar to default: in other languages):

#!/usr/bin/env bash

variable='foo'

case variable in
  # This is where our other patterns to match will go...

  *)
    echo 'We did not match any other pattern'
    ;;
esac

It’s always good to have a catchall, think of it like an else statement, which you can use to catch unexpected values.

With the catchall in place, let’s add a couple of patterns to match again:

#!/usr/bin/env bash

variable='foo'

case variable in
  foo)
    echo 'We matched foo!'
    ;;
  bar)
    echo 'We matched bar!'
    ;;
  *)
    echo 'We did not match any other pattern'
    ;;
esac

The sky’s the limit, add as many (or as few) as you need. Hopefully it’s obvious, but if you need to a single pattern, you’re better off using an if/then/else statement.

Now let’s say that we wanted to run the same block of code against different patterns that are matched. You certainly could duplicate the entire pattern block, but there’s a way better way.

The patterns listed are able to take a pipe | to list out multiple patterns to match:

#!/usr/bin/env bash

variable='foo'

case variable in
  foo | spam)
    echo 'We matched foo or spam!'
    ;;
  bar | eggs)
    echo 'We matched bar or eggs!'
    ;;
  *)
    echo 'We did not match any other pattern'
    ;;
esac

Same deal, list out as many or as few as you need!

Join the Conversation

Good stuff? Want more?

Weekly emails about technology, development, and sometimes sauerkraut.

100% Fresh, Grade A Content, Never Spam.

Related Articles