Date: Wed, 10 Sep 1997 13:39:52 +0100 From: nik@iii.co.uk To: Greg Pavelcak <gpavelcak@philos.umass.edu> Cc: questions@freebsd.org Subject: Re: Redirecting "make world" Output Message-ID: <19970910133952.00934@strand.iii.co.uk> In-Reply-To: <Pine.OSF.3.96.970910073134.26194A-100000@emily.oit.umass.edu>; from Greg Pavelcak on Wed, Sep 10, 1997 at 07:37:46AM -0400 References: <Pine.OSF.3.96.970910073134.26194A-100000@emily.oit.umass.edu>
next in thread | previous in thread | raw e-mail | index | archive | help
[Copied to the mailing list for posterity]
On Wed, Sep 10, 1997 at 07:37:46AM -0400, Greg Pavelcak wrote:
> I believe the upgrade tutorial says you can save the info output of
> make world by redirecting like this (using sh as shell):
>
> make world 2>&1 | tee /var/tmp/mw.out
>
> I saw this 2>&1 construction in the sh man pages but I don't
> understand it. Anyway, the immediate problem is that I get an error
> when I write this. I think it said "ambiguous redirection"
> unfortunately I don't have it with me now.
Hmm. That construct works exactly as shown, under 'sh' as the shell.
If you use csh (or tcsh) it does indeed fail with "Ambiguous output
redirect".
Check which shell you're using,
% echo $SHELL
/usr/local/bin/tcsh
If it doesn't say "/bin/sh", run sh.
The actual redirection works as follows:
When a Unix program starts up, 3 file descriptors are opened for it.
Each file descriptor has a number. By convention[1], descriptor 0 is
STDIN, 1 is STDOUT and 2 is STDERR.
When a program reads user input, it (by default) reads from STDIN. When
it writes output it writes it to STDOUT, and when it writes errors it
sends them to STDERR.
This lets you do input/output redirection. For example, when you run
% ls > /tmp/ls.out
the shell starts 'ls', but starts it with descriptor 1 (STDOUT) redirected
to a file instead of the terminal. A similar thing happens if you do
% grep foo < /tmp/ls.out
(ignoring the fact that you could just specify the filename on grep's
command line) except that the shell arranges for descriptor 0 (STDIN)
to the file /tmp/ls.out instead of the terminal.
STDERR comes into play when programs want to report errors, but they
don't want those errors to be mixed in with their regular output.
For example,
% grep foo non_existant_file > /tmp/grep.out
will echo "grep: non_existant_file: No such file or directory" to the
terminal. The line will *not* be put in /tmp/grep.out. grep explicitly
wrote it's error message to STDERR rather than STDOUT[2].
This is useful, because it allows you to redirect a command's normal
output, but get an immediate view of any errors it might produce.
Of course, if a command generates lots of errors, they might scroll off
the screen and be lost (forgetting about the FreeBSD console's ability
to scrollback with the Scroll Lock key for a moment). For a command
like "make world" this is a bad thing.
The (sh) construct
% program_1 2>&1 | program_2
runs 'program_1' and makes a copy of any messages that program sends to
STDERR to STDOUT. Messages to STDERR are still sent to the console as
normal, they're just copied to STDOUT too.
'program_2' can then read from STDIN and receive all the output from
'program_1', regardless of whether or not it was sent (originally) to
STDOUT or STDERR.
The construct is saying "Take any output from descriptor 2 (STDERR) and
duplicate it in to descriptor 1 (STDOUT)."
At least, that's how it works if you use 'sh' as the shell. csh has a
smaller, more restrictive syntax that doesn't let you do as many fun
things with redirection. However, in this case the construct
% program_1 |& program_2
is equivalent.
Hope that makes sense.
N
[1] This may actually be documented in a standard somewhere, but I don't
know where.
[2] A program must be written to do this. It doesn't happen automatically.
Try
% ls non_existant_file > /tmp/ls.out
No output will be shown on the terminal. /tmp/ls.out will contain the
line
non_existant_file: No such file or directory.
This is (arguably) a bug in ls.
--
--+==[ Nik Clayton is Just Another Perl Hacker at Interactive Investor ]==+--
Diana, the roadkill formally known as Princess, 1961-1997 NC5-RIPE
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19970910133952.00934>
