Tuesday Tiny Techie Tip

csh(1) Redirection

I/O redirection is one of the places where the two different flavors of shell are clearly different. And not just different, but csh and its ilk are clearly inferior. I'll talk about csh redirection this week and cover the Bourne methods next week.

UNIX uses three standard streams for input and output: stdin, stdout, and stderr. stdin is the place from which input comes to a process, stdout is the place where normal output goes, and stderr is the place where error or diagnostic output goes. So a standard unix process looks something like a pipe fitting with one input and two outputs.

a picture of a pipe tee

By default, the input is attached to the input of the terminal starting the process (i.e., your keyboard), and both the output streams are attached to the output of the terminal (i.e., your screen).

Redirection lets you change these attachment points.

There are two basic flavors of redirection, to and from files which uses "<" and ">" characters, and to and from other processes which uses the "|" (pipe) character.

Redirect stdout to a file

% ls > file

Which does something like this:

So stdin and stderr are still attached to the terminal, but anything sent to stdout goes to the file.

If the file already exists, it is truncated before the process is spawned. (unless the "noclobber" shell variable is set in which case redirecting to an existing file is an error.)

If a double angle bracket is used (">>") then the output is appended to the file.

Redirect both stdout and stderr to a file

% ls >& file

Which does something like this:



Here stdout and stderr get combined onto stdout which then gets shunted into the file.

Again, if a double angle bracket is used (">>&") then the output is appended to the file.

Redirect stdin from a file

% wc < file

Which does something like this:

Here stdout and stderr remain attached to the terminal, but input is read from the file.

Redirect stdin from text
This is mostly used in scripts where it is called a "here document"
% wc << END
This is some text
that will be counted
by wc(1).
END

The command reads the input lines after the " << END" up until it sees "END" on a line by itself. The marker can be any string, it doesn't have to be "END".

Pipe one process's stdout to another's stdin
Redirection doesn't have to be to files, but can also work between processes:
% ls | wc

This does something like this:

So the first process's stdout feeds into the second's stdin, both process's stderr still goes to the terminal, and the second process's stdout goes to the terminal.

Pipe one process's stdout and stderr to another's stdin
This works just like a normal pipe, but stderr and stdout get combined onto stdout before passing into the next process's stdin:
% ls |& wc

This does something like this:



So the first process's stderr is combined with stdout which feeds into the second's stdin, the second process's stderr and stdout go to the terminal.

Combinations
And the various methods can be combined:
% sed 's/^#//' < file | wc -l | awk '{print $NF}' >& otherfile

Which does something like this:



Here stdin for the first process comes from a file, stdout for the first process goes to stdin of the second, stdout of the second goes to stdin of the third, and stdout and stderr of the third goes into another file. The first and second process's stderr goes to the terminal.

Next week we'll look at Bourne shell redirection which is far more flexible. (And if you think csh is flexible enough, show me how to capture a process's stderr to a file while letting stdout go to the terminal.)


Tuesday Tiny Techie Tip -- 8 April 1997
Forward to (04/15/97)
Back to (04/01/97)
Written by Jeff Youngstrom

Up to the TTTT index

Tuesday Tiny Techie Tips are all © Copyright 1996-1997 by Jeff Youngstrom. Please ask permission before reproducing any of this material.