The Unix Command Line: Pipes and Redirects

By Mike Darrow

Many UNIX commands take text-like input and/or produce text-like output. It's sometimes useful to be able to control where the input comes from and output goes (via redirection), or even pass the output from one command to another's input (via pipes). This can be used to do fairly complex things, for example, the following command will print a list of misspelled words in the file fnord.txt (it's sort of a primitive spellchecker):

tr 'A-Z' 'a-z' <fnord.txt | tr -cs 'a-z' 'n' | sort | uniq | comm -23 - /usr/share/dict/words

What this does is pass the contents of fnord.txt to the 'tr' command to translate uppercase letters to lowercase; the output from that is piped to another 'tr' command that turns everything except lowercase letters into line breaks (effectively putting each word on a separate line); that's piped to 'sort' which puts the lines (words) in alphabetical order; that's piped to 'uniq', which gets rid of duplicate words; that's piped to 'comm', which compares the words to the dictionary, and prints whatever's not in the dictionary. (Unfortunately, this tends to include plurals, past tense verbs, words that came into use after 1934... it's really not a very good spellchecker.)

Most of the time, pipes and redirects are used aren't nearly that complicated. In fact, there are fairly few idioms that get used over and over. I've tried to illustrate them in the examples below.

pipes and redirects are actually done by the shell interpreter you're running. The simple pipes and redirects described here work essentially the same in all shells, but most shells can also perform other, more obscure, kinds of pipes and redirects (e.g. redirecting error messages along with/instead of standard output). For more details, read the man page for the shell you're using. BTW, the default shell under OS-X is 'tcsh' (except in single-user mode, where it's 'zsh').

>Redirect output from a command to a file on disk. Note: if the file already exists, it will be erased and overwritten without warning, so be careful.
Example: ps -ax >processes.txt

Use the ps command to get a list of processes running on the system, and store the output in a file named processes.txt
>>Append output from a command to an existing file on disk.
Example: ps -ax >>processes.txt

Tack the current process list onto the end of the file processes.txt
<Read a command's input from a disk file, rather than the user. Be careful not to type ">" by mistake, or you'll erase the contents of the file you're trying to read from.
Example: niload -d -r / . </var/backups/local.nidump

Use the niload command to load data from the file /var/backups/local.nidumpinfo into the current NetInfo domain. Without input redirection, you'd have to type the NetInfo data into the terminal by hand (and God help you if you got the syntax slightly wrong...)
|Pass the output of one command to another for further processing.
Example: ps -ax | grep Finder

Use the ps command to get a list of processes running on the system, and pass the list to grep to search for lines containing "Finder". (Usually, it'll find two: the Finder, and the processes executing grep Finder.)
Example: lsof | more

Use the lsof command to list all open files in use on the system, and pass the list to more to display it one screen at a time (rather than just spewing the whole thing directly to the terminal).
teeUsed in the middle of a pipeline, this command allows you to both redirect output to a file, and pass it to further commands in the pipeline.
Example: ps -ax | tee processes.txt | more

Use the ps command to get a list of processes running on the system, store it in the file processes.txt, and also pass it to more to display it one screen at a time. Note that you could get the same result with the two commands:

ps -ax >processes.txt
more processes.txt