read Enhancements
The read command has gotten several small improvements. There is one however that I thought was a real standout. You can now provide a default value that will be accepted if the user presses the Enter key. The new -i option is followed by a string containing the default text. Note that for this option to work, the -e option (which enables the readline library) must also be specified. Here is an example script:
#!/bin/bash
# read4: demo new read command feature
read -e -p "What is your user name? " -i $USER
echo "You answered: '$REPLY'"
When the script is executed, the user is prompted to answer, but a default value is supplied which may be edited if desired:
bshotts@twin7:~$ read4
What is your user name? bshotts
You answered: 'bshotts'
case Improvements
The case compound command has been made more flexible. As you may recall, case performs a multiple choice test on a string. In versions of bash prior to 4.x, 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
Running this script produces this:
bshotts@twin7:~$ 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 alphabetic, as well as a hexadecimal digit. In bash prior to 4.x there was no way for case to match more than one test. In bash 4.x however, 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
Now when we run the script, we get this:
bshotts@twin7:~$ 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. There is also a ";&" syntax which permits case to continue on to the next action regardless of the outcome of the next test.
Further Reading
The bash man page:
- The Compound Commands subsection of the SHELL GRAMMAR section.
- The SHELL BUILTIN COMMANDS section.
- http://bash-hackers.org/wiki/doku.php/commands/builtin/read
- http://bash-hackers.org/wiki/doku.php/syntax/ccmd/case
- http://www.gnu.org/software/bash/manual/bashref.html#Bash-Builtins
- http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs
Very cool. Looking forward to bash updates :)
ReplyDelete