Differences between revisions 5 and 17 (spanning 12 versions)
Revision 5 as of 2007-09-06 12:31:51
Size: 3139
Editor: GreyCat
Comment: bullet lists need a one-space indentation in this wiki
Revision 17 as of 2012-03-05 11:30:04
Size: 3329
Editor: pgas
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
[[Anchor(faq47)]] <<Anchor(faq47)>>
Line 3: Line 3:
                                                                                 A pipe can only carry stdout of a program. To pipe stderr through it, you
need to redirect stderr to the same destination as stdout. Optionally
you can close stdout or redirect it to {{{/dev/null}}} to only get stderr. Some
sample code:
A pipe can only carry standard output (stdout) of a program. To pipe standard error (stderr) through it, you need to redirect stderr to the same destination as stdout. Optionally you can close stdout or redirect it to {{{/dev/null}}} to only get stderr. Some sample code:
Line 10: Line 6:
# Assume 'myprog' is a program that outputs both, stdout and stderr. # Bourne
# Assume 'myprog' is a program that writes to both stdout and stderr.
Line 12: Line 9:
# version 1: redirect stderr towards the pipe while stdout survives (both come # version 1: redirect stderr to the pipe while stdout survives (both come
Line 16: Line 13:
# version 2: redirect stderr towards the pipe without getting stdout (it's # version 2: redirect stderr to the pipe without getting stdout (it's
Line 20: Line 17:
# version 3: redirect stderr towards the pipe while the "original" stdout gets
# closed
myprog 2>&1 >&- | grep ...
# same idea, this time storing stdout in a file
myprog 2>&1 >file | grep ...
Line 25: Line 21:
For further explanation of how redirections and pipes interact, see [#faq55 FAQ #55]. Another simple example of redirection stdout and stderr:
{{{
# Bourne
{ command | stdout_reader; } 2>&1 | stderr_reader
}}}
Line 27: Line 27:
This has an obvious application with programs like {{{dialog}}}, which draws (using ncurses) windows onto the screen (stdout), and returns results on stderr. One way to deal with this would be to redirect stderr to a temporary file. But this is not necessary -- see [#faq40 FAQ #40] for examples of using dialog specifically! For further explanation of how redirections and pipes interact, see [[BashFAQ/055|FAQ #55]].
Line 29: Line 29:
In the examples above (as well as [#faq40 FAQ #40]), we either discarded stdout altogether, or sent it to a known device ({{{/dev/tty}}} for the user's terminal). One may also pipe stderr only but keep stdout intact (without ''a priori'' knowledge of where the script's output is going). This is a bit trickier. This has an obvious application with programs like {{{dialog}}}, which draws (using ncurses) windows onto the screen (stdout), and returns results on stderr. One way to deal with this would be to redirect stderr to a temporary file. But this is not necessary -- see [[BashFAQ/040|FAQ #40]] for examples of using dialog specifically!

In the examples above (as well as [[BashFAQ/040|FAQ #40]
]), we either discarded stdout altogether, or sent it to a known device ({{{/dev/tty}}} for the user's terminal). One may also pipe stderr only but keep stdout intact (without ''a priori'' knowledge of where the script's output is going). This is a bit trickier.
Line 32: Line 34:
# Bourne
Line 43: Line 46:
$ myfunc () { echo "I'm stdout"; echo "I'm stderr" >&2;}
$ { myfunc 2>&1 1>&3- | cat > stderr.file 3>&- ; } 3>&1
# POSIX
$ myfunc () { echo "I'm stdout"; echo "I'm stderr" >&2; }
$ { myfunc 2>&1 1>&3 3>&- | cat > stderr.file 3>&-; } 3>&1
Line 50: Line 54:
The fd 3 is closed (1>&3- and 3>&-) so that the commands do not inherit it. The fd 3 is closed (3>&-) so that the commands do not inherit it. Note bash allows to duplicate and close in one redirection: 1>&3-
Line 53: Line 57:
# Bash
Line 59: Line 64:
# Bourne
Line 66: Line 72:
A similar effect can be achieved with process substitution: A similar effect can be achieved with ProcessSubstitution:
Line 68: Line 74:
# Bash only.
perl -e 'print "stdout\n"; warn "stderr\n"' 2> >(tr a-z A-Z)
# Bash
perl -e 'print "stdout\n"; warn "stderr\n"' 2> >(tr '[:lower:]' '[:upper:]')
Line 74: Line 80:
A redirection tutorial (with an example that redirects stdout to a pipe and stderr to another pipe):
 * http://bash-hackers.org/wiki/doku.php?id=howto:redirection_tutorial
See this [[http://wiki.bash-hackers.org/howto/redirection_tutorial|redirection tutorial]] (with an example that redirects stdout to one pipe and stderr to another pipe).

----
Ca
tegoryShell

How can I redirect stderr to a pipe?

A pipe can only carry standard output (stdout) of a program. To pipe standard error (stderr) through it, you need to redirect stderr to the same destination as stdout. Optionally you can close stdout or redirect it to /dev/null to only get stderr. Some sample code:

# Bourne
# Assume 'myprog' is a program that writes to both stdout and stderr.

# version 1: redirect stderr to the pipe while stdout survives (both come
# mixed)
myprog 2>&1 | grep ...

# version 2: redirect stderr to the pipe without getting stdout (it's
# redirected to /dev/null)
myprog 2>&1 >/dev/null | grep ...

# same idea, this time storing stdout in a file
myprog 2>&1 >file | grep ...

Another simple example of redirection stdout and stderr:

# Bourne
{ command | stdout_reader; } 2>&1 | stderr_reader

For further explanation of how redirections and pipes interact, see FAQ #55.

This has an obvious application with programs like dialog, which draws (using ncurses) windows onto the screen (stdout), and returns results on stderr. One way to deal with this would be to redirect stderr to a temporary file. But this is not necessary -- see FAQ #40 for examples of using dialog specifically!

In the examples above (as well as FAQ #40), we either discarded stdout altogether, or sent it to a known device (/dev/tty for the user's terminal). One may also pipe stderr only but keep stdout intact (without a priori knowledge of where the script's output is going). This is a bit trickier.

# Bourne
# Redirect stderr to a pipe, keeping stdout unaffected.

exec 3>&1                       # Save current "value" of stdout.
myprog 2>&1 >&3 | grep ...      # Send stdout to FD 3.
exec 3>&-                       # Now close it for the remainder of the script.

# Thanks to http://www.tldp.org/LDP/abs/html/io-redirection.html

The same can be done without exec:

# POSIX
$ myfunc () { echo "I'm stdout"; echo "I'm stderr" >&2; }
$ { myfunc 2>&1 1>&3 3>&- | cat  > stderr.file 3>&-; } 3>&1
I'm stdout
$ cat stderr.file
I'm stderr

The fd 3 is closed (3>&-) so that the commands do not inherit it. Note bash allows to duplicate and close in one redirection: 1>&3- You can check the difference on linux trying the following:

# Bash
{ bash <<< 'lsof -a -p $$ -d1,2,3'   ;} 3>&1
{ bash <<< 'lsof -a -p $$ -d1,2,3' 3>&-  ;} 3>&1

To show a dialog one-liner:

# Bourne
exec 3>&1
dialog --menu Title 0 0 0 FirstItem FirstDescription 2>&1 >&3 | sed 's/First/Only/'
exec 3>&-

This will have the dialog window working properly, yet it will be the output of dialog (returned to stderr) being altered by the sed.

A similar effect can be achieved with ProcessSubstitution:

# Bash
perl -e 'print "stdout\n"; warn "stderr\n"' 2> >(tr '[:lower:]' '[:upper:]')

This will pipe standard error through the tr command.

See this redirection tutorial (with an example that redirects stdout to one pipe and stderr to another pipe).


CategoryShell

BashFAQ/047 (last edited 2012-03-05 11:30:04 by pgas)