msgbartop
Adam Palmer MBCS CITP, Linux, PHP Programmer, MySQL Developer, Embedded Hardware, Security Consultant
Did my blog help you? Please link to me!
  dns test
 
RSS Feed
msgbarbottom

07 Mar 09 Linux piping and redirecting stdin stderr stdout

We have three relevant streams when dealing with passing data around on the command line. STDIN (0), STDOUT (1) and STDERR (2)

echo “hello” will return “hello” to STDOUT

echo “hello” | sed s/llo/y/g
Returns: ‘hey’

echo “hello” will print “hello” to STDOUT which we pipe to sed’s STDIN. The shell will fork both processes, echo and sed, and create a pipe between one’s STDOUT to the other’s STDIN. A ‘broken pipe’ will occur when one terminates unexpectedly.

strace echo “hello” will print the system calls that the command makes. Lets say I just want to print out open() calls.

strace echo “hello” | grep open does not work. It seems that the grep is ignored.

This is because strace sends it’s output to STDERR and not STDOUT. In this case we must redirect STDERR to STDOUT so grep can pick it up on it’s STDIN.

strace echo “hello” 2>&1 | grep open will work successfully.

What if we want to redirect STDOUT and STDERR to a file? We simply redirect STDOUT to a file and then redirect STDERR to STDOUT.

strace echo “hello” >/tmp/strace.output 2>&1

A nonstandard method of achieving the same by redirecting everything in one go is strace echo “hello” &>/tmp/strace.output however this is not guaranteed to work across all implementations.

* Post edited thanks to observations from Adam Bolte (16/11/09)

Tags: , , , , , , ,



Reader's Comments

  1. |

    The redirection of both stderr and stdout to single file is very useful. Thanks.

    unstableme.blogspot.com

  2. |

    What if I wish to redirect stderr ONLY to stdin???

    I have an application (say ‘appl1′) that outputs both to stdout and stderr. I wish to pipe the stderr to application ‘appl2′. How do I do that???

  3. |

    See http://tldp.org/LDP/abs/html/io-redirection.html “Closing File Descriptors” part

  4. |

    Actually, there is a problem with the command you presented to redirect stdout and stderr to a file. At least on a GNU/Linux OS, it should actually look like this:

    $ command >/tmp/command.output 2>&1

    The way you did it, you are saying:
    1. Redirect stderr to wherever stdout is currently pointing to.
    2. Redirect stdout to /tmp/command.output

    However, stderr redirection isn’t modified with stdout. You need to reverse the order of the commands so when stderr points to whatever stdout is pointing to, stdout is directed to the file already.

    @Karas:
    You would redirect stderr to whatever stdout is pointing to, and then change stdout to point to /dev/null. eg.
    $ command 2>&1 >/dev/null



Leave a Comment