Previous | Table of Contents | Next |
A common task in shell scripts is to prompt users for input and then read their responses. To do this, use the read command to set the value of a variable and then evaluate the value of the variable with a case statement.
The read command works as follows:
read name
It reads the entire line of user input until the user presses return and makes that line the value of the variable specified by name.
An example of this is
YN=yes printf "Do you want to play a game [$YN]? " read YN : ${YN:=yes} case $YN in [yY]|[yY][eE][sS]) exec xblast ;; *) echo "Maybe later." ;; esac
Here you prompt the user and provide a default response. Then you read and evaluate the users answer using a case statement.
A common use of input redirection in conjunction with the read command is the reading of a file one line at a time using the while loop. The basic syntax is
while read LINE do : # manipulate file here done < file
In the body of the while loop, you can manipulate each line of the specified file. A simple example of this is
while read LINE do case $LINE in *root*) echo $LINE ;; esac done < /etc/passwd
Here only the lines that contain the string root in the file /etc/passwd are displayed. On my system, the output looks like:
root:x:0:1:Super-User:/:/sbin/sh
In Chapters 16, Filtering Text Using Regular Expressions, 17, Filtering Text with awk, and 18, Miscellaneous Tools, I will show you how to use more powerful filters in place of the case statement used here.
Most commands in UNIX that are designed to work with files can also read input from STDIN. This enables you to use one program to filter the output of another. This is one of the most common tasks in shell scripting: having one program manipulate the output of another program.
You can redirect the output of one command to the input of another command using a pipeline, which connects several commands together with pipes as follows:
command1 | command2 | ...
The pipe character, |, connects the standard output of command1 to the standard input of command2, and so on. The commands can be as simple or complex as are required.
Here are some examples of pipeline commands:
tail -f /var/adm/messages | more ps -ael | grep "$UID" | more
In the first example, the standard output of the tail command is piped into the standard input of the more command, which enables the output to be viewed one screen at a time.
In the second example, the standard output of ps is connected to the standard input of grep, and the standard output of grep is connected to the standard input of more, so that the output of grep can be viewed one screen at a time. For now, simply be aware of this technique of redirection. I show you how to use it to filter text in Chapters 16, 17, and 18.
Caution:
One important thing about pipelines is that each command is executed as a separate process, and the exit status of a pipeline is the exit status of the last command.It is vital to remember this fact when writing scripts that must do error handling.
When you issue any command, three files are opened and associated with that command. In the shell, each of these files is represented by a small integer called a file descriptor. A file descriptor is a mechanism by which you can associate a number with a filename and then use that number to read and write from the file. Sometimes file descriptors are called file handles.
The three files opened for each command along with their corresponding file descriptors are
The integer following each of these files is its file descriptor. Usually, these files are associated with the users terminal, but they can be redirected into other files.
In the previous examples in this chapter, you have used input and output redirection using the default file descriptors. This section introduces the general form of input and output redirection.
First you examine associating files with a file descriptor.
Previous | Table of Contents | Next |