< Previous | Contents | Next >
Performing Multiple Actions
In versions of bash prior to 4.0, case allowed only one action to be performed on a successful match. After a successful match, the command would terminate. Here we see a script that tests a character:
#!/bin/bash
# case4-1: test a character
read -n 1 -p "Type a character > " echo
case $REPLY in
[[:upper:]]) echo "'$REPLY' is upper case." ;;
[[:lower:]]) echo "'$REPLY' is lower case." ;;
[[:alpha:]]) echo "'$REPLY' is alphabetic." ;;
[[:digit:]]) echo "'$REPLY' is a digit." ;; [[:graph:]]) echo "'$REPLY' is a visible character." ;;
[[:punct:]]) echo "'$REPLY' is a punctuation symbol." ;; [[:space:]]) echo "'$REPLY' is a whitespace character." ;; [[:xdigit:]]) echo "'$REPLY' is a hexadecimal digit." ;;
esac
#!/bin/bash
# case4-1: test a character
read -n 1 -p "Type a character > " echo
case $REPLY in
[[:upper:]]) echo "'$REPLY' is upper case." ;;
[[:lower:]]) echo "'$REPLY' is lower case." ;;
[[:alpha:]]) echo "'$REPLY' is alphabetic." ;;
[[:digit:]]) echo "'$REPLY' is a digit." ;; [[:graph:]]) echo "'$REPLY' is a visible character." ;;
[[:punct:]]) echo "'$REPLY' is a punctuation symbol." ;; [[:space:]]) echo "'$REPLY' is a whitespace character." ;; [[:xdigit:]]) echo "'$REPLY' is a hexadecimal digit." ;;
esac
Running this script produces this:
[me@linuxbox ~]$ case4-1
Type a character > a
'a' is lower case.
[me@linuxbox ~]$ case4-1
Type a character > a
'a' is lower case.
The script works for the most part, but fails if a character matches more than one of the POSIX characters classes. For example, the character "a" is both lower case and alpha- betic, as well as a hexadecimal digit. In bash prior to version 4.0 there was no way for case to match more than one test. Modern versions of bash, add the “;;&” notation to
terminate each action, so now we can do this:
#!/bin/bash
# case4-2: test a character
read -n 1 -p "Type a character > " echo
case $REPLY in
[[:upper:]]) echo "'$REPLY' is upper case." ;;&
[[:lower:]]) echo "'$REPLY' is lower case." ;;&
[[:alpha:]]) echo "'$REPLY' is alphabetic." ;;&
[[:digit:]]) echo "'$REPLY' is a digit." ;;& [[:graph:]]) echo "'$REPLY' is a visible character." ;;&
[[:punct:]]) echo "'$REPLY' is a punctuation symbol." ;;& [[:space:]]) echo "'$REPLY' is a whitespace character." ;;& [[:xdigit:]]) echo "'$REPLY' is a hexadecimal digit." ;;&
esac
#!/bin/bash
# case4-2: test a character
read -n 1 -p "Type a character > " echo
case $REPLY in
[[:upper:]]) echo "'$REPLY' is upper case." ;;&
[[:lower:]]) echo "'$REPLY' is lower case." ;;&
[[:alpha:]]) echo "'$REPLY' is alphabetic." ;;&
[[:digit:]]) echo "'$REPLY' is a digit." ;;& [[:graph:]]) echo "'$REPLY' is a visible character." ;;&
[[:punct:]]) echo "'$REPLY' is a punctuation symbol." ;;& [[:space:]]) echo "'$REPLY' is a whitespace character." ;;& [[:xdigit:]]) echo "'$REPLY' is a hexadecimal digit." ;;&
esac
When we run this script, we get this:
[me@linuxbox ~]$ case4-2
Type a character > a 'a' is lower case. 'a' is alphabetic.
'a' is a visible character. 'a' is a hexadecimal digit.
[me@linuxbox ~]$ case4-2
Type a character > a 'a' is lower case. 'a' is alphabetic.
'a' is a visible character. 'a' is a hexadecimal digit.
The addition of the ";;&" syntax allows case to continue on to the next test rather than simply terminating.