UNIX Pipelines And I/O Redirections

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 mispelled 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 seperate 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 times 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.

Note: 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 exist, 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.

Examples:

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.)
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).

tee
– Used 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.

Examples:

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

Leave a Reply