Chapter 1: UNIX Basics
Objectives



cover.gif

In this chapter, you will learn about:



Piping Secrets

Piping Standard Error

As mentioned in the book, you will only rarely need to pipe standard error into a command; you can almost always get away with saving standard error in a file (using 2> file redirection) and then using that file as input to a command.

However, should you ever need to do this and for some reason that won’t work, here’s how you can pipe standard error.

Remember that the shell offers you ten different file descriptors, even though you normally use only three (standard input, standard output, and standard error). Pipes always read off of file descriptor one (standard output). In order to pipe standard error, you need to make standard error point to file descriptor one instead of file descriptor two.

You already know how to do that: use the 2>&1 format. However, it’s a little trickier than that.

Try this:

$ print hello | more

This command just demonstrates the print command (which writes to standard output) and the more command (which reads from standard input). Now type:

$ print -u2 goodbye | more

This command demonstrates that more doesn’t read from standard error: the -u2 option makes print write to standard error instead of standard output.

Now, enter this command so you can generate both standard input and standard error:

$ (print hello;print -u2 goodbye) | more

The parentheses tell the shell to run both print commands in a subshell. (This ability to "merge" the standard outputs of several commands is the real reason to use parentheses in pipelines.) In this case, only the "hello" is piped into more.

Now try swapping standard input and standard using the 2>&1 format:

$ (print hello;print -u2 goodbye) 2>&1 1>&2 | more

The results are wrong…both "hello" and "goodbye" show up in more. Why?

Remember that 2>&1 tells the shell to assign all the stuff in file stream 1 to file stream 2, and the second tells the shell to apply everything in file stream 2 (that is, both stdout and stderr now) to file stream 1. So the problem is that you "mixed" the two streams and now cannot unmix them.

How do you pipe only standard error? Simple: don’t mix them. Send the contents of stream 2 (standard error) someplace else first, like this:

$ (print hello;print -u2 goodbye) 3>&2 2>&1 1>&3 | more

This says, in effect:

1. Shuffle the stuff from standard error over to stream 3, which doesn’t have a special name.

2. Then move the stuff from standard output over to stream 2, which used to be standard error.

3. Then move the stuff in stream 3 (standard error, remember?) to stream 1, which used to be standard output.

Confusing? Yes. But I need it about once a year. You may need it less.


© 1999-2000 by Prentice-Hall, Inc.
A Pearson Company
Distance Learning at Prentice Hall
Legal Notice