From owner-freebsd-questions Wed Sep 10 05:37:47 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id FAA28084 for questions-outgoing; Wed, 10 Sep 1997 05:37:47 -0700 (PDT) Received: from tyree.iii.co.uk (tyree.iii.co.uk [193.117.77.66]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id FAA28076 for ; Wed, 10 Sep 1997 05:37:43 -0700 (PDT) Received: from carrig.strand.iii.co.uk (carrig.strand.iii.co.uk [192.168.7.25]) by tyree.iii.co.uk (8.8.4/8.8.4) with ESMTP id NAA12773; Wed, 10 Sep 1997 13:34:23 +0100 (BST) Received: (from nik@localhost) by carrig.strand.iii.co.uk (8.8.7/8.8.7) id NAA01720; Wed, 10 Sep 1997 13:39:53 +0100 (BST) Message-ID: <19970910133952.00934@strand.iii.co.uk> Date: Wed, 10 Sep 1997 13:39:52 +0100 From: nik@iii.co.uk To: Greg Pavelcak Cc: questions@freebsd.org Subject: Re: Redirecting "make world" Output References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 0.76e In-Reply-To: ; from Greg Pavelcak on Wed, Sep 10, 1997 at 07:37:46AM -0400 Organization: interactive investor Sender: owner-freebsd-questions@freebsd.org X-Loop: FreeBSD.org Precedence: bulk [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