#!/bin/sh # Yes, you can execute this whole script for demonstration. # Of course you also remember comments, the here document, and the : # command, right? :-) Okay, so I effectively (but not literally) # comment out the part between the pairs of __EOT__ without having to # individually comment out most or all the lines in that section. >>/dev/null 2>&1 : << \__EOT__ # case syntax: case word in [ pattern [ | pattern ] ... ) list ;; ] ... esac # here the square bracket ([]) characters aren't meant literally, # but rather indicate the enclosed portion is optional # the ... indicates the preceding (optional) portions can be # repeated zero or more times # so, let's look again, in some more detail: case word in [ pattern [ | pattern ] ... ) list ;; ] ... esac #word is a word - sequence of one or more non-blank characters (can #---- contain blanks if quoted, can be result of # various types of substitution, can be null if # quoted) # pattern a pattern specification to potentially match word # ------- against, as described under File name generation # on sh(1) # | pattern - multiple patterns can be specified # --------- by separating them with | # ) # - literal right parenthesis # character # list list to be executed if # ---- preceeding corresponding # pattern(s) match (only # the first list matching # pattern is executed) # ;; ] ... esac # ------------- # ;; effectively marks the # end of list # corresponding to the # preceeding pattern(s), # an arbitrary number of # pattern through list ;; # portions can be # specified, at most one # list is executed (that # corresponding to the # first pattern in the # case that's matched), # the esac is keyword # needed to end the case # command # where we must/can/can't have "blanks" (one or more space(s) and/or # tab(s)) and/or "whitespace" (one or more "blanks" and/or newline(s)) # (see also examples): # we need blanks between case and word # we need whitespace between word and pattern # we can have blanks around | separating patterns # we can have blanks between pattern and ) # we can have whitespace between ) and list # we can have whitespace between list and ;; # we must have whitespace between list and ;; if list ends with # semicolon (;) # we can have whitespace between ;; and pattern or esac __EOT__ # if $1 is not set, we set it to 15 # "${1-15}" gives us "$1" if $1 is set, "15" otherwise # we then use set to set that as our first (and now only) positional parameter set -- "${1-15}" # as side effect, we unset an other positional parameters # you can execute this script with arguments, to change $1 from the default # value of 15 # you can also try with it unset or try setting it to something that # doesn't match the first set of patterns that's used for most of the # examples # We'll track if we got error(s), rather than immediately bailing out error=no # Typical fairly readable use in scripts: case "$1" in [0-9]|[1-9][0-9]) echo OK ... ;; *) 1>&2 echo "$0: expecting \$1 between 0 and 99, got $1" error=yes ;; esac # Typical fairly readable use in scripts with a bit more liberal # whitespace: case "$1" in [0-9] | [1-9][0-9] ) echo OK ... ;; * ) 1>&2 echo "$0: expecting \$1 between 0 and 99, got $1" error=yes ;; esac # Very difficult to read version with same functionality with an # unquoted newline everywhere we can get away with using it for # whitespace, no unneeded blanks, and no tabs: case "$1" in [0-9]|[1-9][0-9]) echo OK ... ;; *) 1>&2 echo "$0: expecting \$1 between 0 and 99, got $1" error=yes ;; esac # without newlines: case "$1" in [0-9]|[1-9][0-9]) echo OK ...;; *) 1>&2 echo "$0: expecting \$1 between 0 and 99, got $1"; error=yes;; esac # note that in the example above, our only use of ; (other than ;;) is # where we require it within a list # even less readable version with minimum whitespace and no newlines case "$1" in [0-9]|[1-9][0-9])echo OK ...;;*)1>&2 echo "$0: expecting \$1 between 0 and 99, got $1";error=yes;;esac # note also from the syntax, that most sections are optional, so we can # also have quite trivial valid case commands: case '' in esac case '' in esac # did we get any errors that we tracked? if [ X"$error" = Xyes ]; then 1>&2 echo "$0: we didn't pass some of our tests, aborting" exit 1 else echo "$0: we completed our tests successfully." exit 0 fi