Sunday, January 16, 2011

How to pipe stderr without piping stdout

How do I pipe the standard error stream without piping the standard out stream?

I know this command works, but it also writes the standard out.

Command 2>&1 | tee -a $LOG

How do I get just the standard error?

Note: What I want out of this is to just write the stderr stream to a log and write both stderr and stdout to the console.

  • To do that, use one extra file descriptor to switch stderr and stdout:

    find /var/log 3>&1 1>&2 2>&3 | tee foo.file
    

    Basically, it works, or at least I think it works, as follows:
    The re-directions are evaluated left-to-right.

    3>&1 Makes a new file descriptor, 3 a duplicate (copy) of fd 1 (stdout).

    1>&2 Make stdout (1) a duplicate of fd 2 (stderr)

    2>&3 Make fd 2, a duplicate (copy) of 3, which was previously made a copy of stdout.

    So now stderr and stdout are switched.

    | tee foo.file tee duplicates file descriptor 1 which was made into stderr.

    Kyle Brandt : Oh, not tested with ksh, works with bash though ...
    C. Ross : Thanks, works in ksh too. I think most of the pipe and stream things are posix standard.
  • according to the man page for ksh (pdksh), you can just do:

    Command 2>&1 >/dev/null | cat -n

    i.e. dup stderr to stdout, redirect stdout to /dev/null, then pipe into 'cat -n'

    works on pdksh on my system:

    $ errorecho(){ echo "$@" >&2;}
    
    $ errorecho foo
    foo
    
    $ errorecho foo >/dev/null   # should still display even with stdout redirected
    foo
    
    $ errorecho foo 2>&1 >/dev/null | cat -n
         1  foo
    $   
    

0 comments:

Post a Comment