We’ve just seen how to invoke external programs. Sometimes we need more control than that. Perhaps we need to obtain the output from those programs, provide input, or even chain together multiple external programs. Piping can help with all of these needs. Piping is often used in shell scripts. When you set up a pipe in the shell, you run multiple programs. The output of the first program is sent to the input of the second. Its output is sent to the third as input, and so on. The last program’s output normally goes to the terminal, or it could go to a file. Here’s an example session with the POSIX shell to illustrate piping:
ls /etc | grep 'm.*ap' | tr a-z A-ZIDMAPD.CONF MAILCAP MAILCAP.ORDER MEDIAPRM TERMCAP
This command runs three programs, piping
data between them. It starts with
ls /etc, which outputs a list of all
files or directories in
ls is sent as input to
grep. We gave
grep a regular expression that will cause it
to output only the lines that start with
'm' and then contain
"ap" somewhere in the line. Finally, the
result of that is sent to
tr. We gave
tr options to convert everything to
uppercase. The output of
tr isn’t set
anywhere in particular, so it is displayed on the screen.
In this situation, the shell handles setting up all the pipelines between programs. By using some of the POSIX tools in Haskell, we can accomplish the same thing.
Before describing how to do this, we
should first warn you that the
System.Posix modules ...