home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  

UNIX Power Tools

UNIX Power ToolsSearch this book
Previous: 45.31 Nested Command Substitution Chapter 45
Shell Programming for the Initiated
Next: 45.33 Testing Two Strings with One case Statement

45.32 A Better read Command: grabchars

grabchars gets characters from the user as they are typed in, without having to wait for the RETURN key to be pressed. Among other things, this allows shell scripts to be written with highly interactive menus.

By default, grabchars will obtain one character from the standard input, echo that character to the standard output, and return an exit status (44.7 ) of one - meaning one character was read. Options (see the manual page) accept more than one character, accept only certain characters, prompt the user, and more.

Here's an example. With the standard echo (8.6 ) and read (44.13 ) commands, you'd prompt a user this way:

echo -n "Answer y or n, then press RETURN: "
read ans

With grabchars , a prompt can be printed to standard error, the user's answer read as soon as the character is pressed, and backquotes (9.16 ) used to grab the standard output (the user's answer, echoed by grabchars ):

ans=`grabchars -q'Answer y or n: '`

By default, the answer that grabchars reads and echoes will be "eaten" by the backquotes; the user won't see what she typed. That's nice when the answer needs to be a secret. To show the answer, you have two choices:

  • You can use the -b option. grabchars will echo the answer to both stdout (which the backquotes read) and stderr (which is usually the terminal).

  • You can also use one of my favorite tricks, completing the user's answer before their eyes. For example, if the user types y , the script echoes yes . An n answer echoes as no . Any other answer (x ) echoes as: x ? Please answer y or n . Here's that sample code, including a while loop (44.10 ) to repeat until the user types the right answer:

    while :
        ans=`grabchars -q'Answer y or n: '`
        case "$ans" in
    y) echo "yes" 1>&2; break ;;
        n) echo "no" 1>&2; break ;;
        *) echo "${ans}?  Please answer y or n." 1>&2 ;;

The option -c valid-characters tells grachars to accept only characters listed in valid-characters (this can be a regular expression like [a-z] ). If the user types something that isn't listed, grabchars will ignore the answer and wait. So, to accept only y or n :

ans=`grabchars -c'yn' -q'Answer y or n: '`

There are lots of other options. I'd like to explain two more. (Please look at the manual page for the rest.) You can give grabchars a time limit with the -t option. If the user doesn't answer by then, grabchars can quit - and also give a default answer from the -d option. The timeout option lets you write shell scripts where you can offer some assistance if it's obvious that the user might be stuck - or to let a user answer a prompt only if he doesn't want the default. For example:

ans=`grabchars -t5 -d'y' -q'To stop, type n within 5 seconds: '`

If the user doesn't type anything in 5 seconds, grabchars will answer y automatically.

- JP , DS

Previous: 45.31 Nested Command Substitution UNIX Power Tools Next: 45.33 Testing Two Strings with One case Statement
45.31 Nested Command Substitution Book Index 45.33 Testing Two Strings with One case Statement

The UNIX CD Bookshelf NavigationThe UNIX CD BookshelfUNIX Power ToolsUNIX in a NutshellLearning the vi Editorsed & awkLearning the Korn ShellLearning the UNIX Operating System