Welcome to sysadvent.org.

Each day until christmas a small nugget will be published here to easen up the waiting time until christmas.

We will have easy start with something I found in the man-pages of bash a while ago.

When dealing with case loops in bash, the syntax is fairly simple:

case ${something} in
  pattern_a)
    echo A
    ;;
  pattern_b
    echo B
    ;;&
  pattern_c)
    echo C
    ;&
  pattern_d)
    echo D
    ;;&
  *)
    echo ALL
    ;;
esac

This is probably the most common way of using this condition. Just some comments on this example:

  • : Is ist just a placeholder that does nothing. The code will run fine, just not do anything. Without the colon, bash throws a parsing error.
  • *): The fallback condition. It is always nice to have one, just to make sure what is going to happen, if none of the patterns match.
  • ;;: The double-semicolon will end the pattern machting after running the commands[1-3] associated with the matching patterns. If pattern1 machtes, commands1 will be executred, etc.

This is fairly common knowledge. When reading the man page of bash about this particular condition, there is more to it (highlighting by me):

A case command first expands word, and tries to match it against each pat‐ tern in turn, using the same matching rules as for pathname expansion (see Pathname Expansion below). The word is expanded using tilde expansion, parameter and variable expansion, arithmetic substitution, command substitu‐ tion, process substitution and quote removal. Each pattern examined is expanded using tilde expansion, parameter and variable expansion, arithmetic substitution, command substitution, and process substitution. If the shell option nocasematch is enabled, the match is performed without regard to the case of alphabetic characters. When a match is found, the corresponding list is executed. If the ;; operator is used, no subsequent matches are attempted after the first pattern match. Using ;& in place of ;; causes execution to continue with the list associated with the next set of pat‐ terns. Using ;;& in place of ;; causes the shell to test the next pattern list in the statement, if any, and execute any associated list on a success‐ ful match. The exit status is zero if no pattern matches. Otherwise, it is the exit status of the last command executed in list.

This means using ;& and ;;& you have even more control about the commands.

With the code example above this means if the variable $something has been set to

  • pattern_a: The output will be simply A. There is just one match and the double-semicolon ;; in the section of pattern_a terminates the condition.
  • patterm_b: The output will be B ALL. Obviously pattern_b matches, but the following ;;& will re-evaluate the content of $something and the fallback *) does match everything.
  • pattern_c: The output will be C D. pattern_c matches and the following ;& will run the following statement as well, independent of its match (pattern_d). Since the section in pattern_d terminates with the double colon ;;, the evalution ends there. It could have been also anything else from ;& and ;;& and then continue the process.
  • pattern_d: The output will be D ALL The pattern pattern_d is evaluated, but so is the rest of all patterns - which is only the default fallback which fits all other patterns.