Unix Shell - Pipe stderr and stdout

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > August 2007 > Pipe stderr and stdout





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Pipe stderr and stdout
Frederic Mayot

2007-08-29, 7:26 pm

Hi,
I'd like to pipe stdout and stderr from appA to appB and appC (appB
reads stdout and appC reads stderr).
"2|" like "2>" does not seem to exist in bash, so something like the
following is not valid
appA | appB 2| appC
How can I do that?
Thanks,
Fred

Icarus Sparry

2007-08-29, 7:26 pm

On Wed, 29 Aug 2007 11:42:31 -0700, Frederic Mayot wrote:

> Hi,
> I'd like to pipe stdout and stderr from appA to appB and appC (appB
> reads stdout and appC reads stderr).
> "2|" like "2>" does not seem to exist in bash, so something like the
> following is not valid
> appA | appB 2| appC
> How can I do that?
> Thanks,
> Fred


Where exactly do you want to pipe the stderr of appA to? If you just want
to pipe it to the stdin of appB, then

appA 2>&1 | appB

will send both stdout and stderr of appA to stdin of appB, or

appA 2>&1 1>/dev/null | appB

will send stderr of appA to appB, and throw away stdout of appA.

Frederic Mayot

2007-08-30, 1:20 pm

On Aug 29, 7:16 pm, Icarus Sparry <use...@icarus.freeuk.com> wrote:
> On Wed, 29 Aug 2007 11:42:31 -0700, Frederic Mayot wrote:
>
> Where exactly do you want to pipe the stderr of appA to? If you just want
> to pipe it to the stdin of appB, then
>
> appA 2>&1 | appB
>
> will send both stdout and stderr of appA to stdin of appB, or
>
> appA 2>&1 1>/dev/null | appB
>
> will send stderr of appA to appB, and throw away stdout of appA.


Oh sorry, I thougth it was obvious.
appA.stderr --> appC.stdin
appA.stdout --> appB.stdin

Edward Rosten

2007-08-30, 1:20 pm

On Aug 29, 12:42 pm, Frederic Mayot <f...@mayot.net> wrote:
> Hi,
> I'd like to pipe stdout and stderr from appA to appB and appC (appB
> reads stdout and appC reads stderr).
> "2|" like "2>" does not seem to exist in bash, so something like the
> following is not valid
> appA | appB 2| appC
> How can I do that?


Pipe command to appB, take the pipeline as a compound, swap stderr and
stdout, then pipe to appC:

{ some_random_command | appB; } 3>&1 1>&2 2>&3 | appC

Assuming that appB and appC both generate stdout, then appB will
appear on stderr, and appC will appear on stdout. To reverse it,
include another swap:

{ { some_random_command | appB; } 3>&1 1>&2 2>&3 | appC; } 3>&1 1>&2
2>&3

If appB and appC generate stderr, then it will become mixed, so you'll
need to discard that:

{ some_random_command | appB 2> /dev/null ; } 3>&1 1>&2 2>&3 | appC
2> /dev/null


-Ed


Frederic Mayot

2007-08-30, 1:20 pm

On Aug 30, 12:36 pm, Edward Rosten <Edward.Ros...@gmail.com> wrote:
> On Aug 29, 12:42 pm, Frederic Mayot <f...@mayot.net> wrote:
>
>
> Pipe command to appB, take the pipeline as a compound, swap stderr and
> stdout, then pipe to appC:
>
> { some_random_command | appB; } 3>&1 1>&2 2>&3 | appC
>
> Assuming that appB and appC both generate stdout, then appB will
> appear on stderr, and appC will appear on stdout. To reverse it,
> include another swap:
>
> { { some_random_command | appB; } 3>&1 1>&2 2>&3 | appC; } 3>&1 1>&2
> 2>&3
>
> If appB and appC generate stderr, then it will become mixed, so you'll
> need to discard that:
>
> { some_random_command | appB 2> /dev/null ; } 3>&1 1>&2 2>&3 | appC
> 2> /dev/null
>
> -Ed


Thanks a lot !

Icarus Sparry

2007-08-31, 1:18 am

On Thu, 30 Aug 2007 07:53:45 -0700, Frederic Mayot wrote:

> On Aug 29, 7:16 pm, Icarus Sparry <use...@icarus.freeuk.com> wrote:
>
> Oh sorry, I thougth it was obvious.
> appA.stderr --> appC.stdin
> appA.stdout --> appB.stdin


OK, that helps. A difficulty with the pipe notation is that it is very
linear. You could make a good case for appA | appB 2| appC to mean sending
the stderr of appB to stdin of appC.

Here is how I would do it for a simple command

#!/bin/sh
# Make some alternative names for the overall stdout and stderr
exec 1>&3 2>&4
# we now start a group of commands
{
# we start appA as normal, feeding its stdout to appB
# appB has its stdout and stderr sent to the original places
appA | appB 2>&4 1>&3
# We send any remaining stderr (which can only come from appA, as appB's
# stderr is redirected) to the stdin of appC
} 2>&1 | appC

If we are doing this for a production script then you should add 3>&- and
4>&- in 3 places so extra open file descriptors are not passed to the
programs.

The "rc" shell by Tom Duff has a much nicer syntax for much of this. You
can specify "|[2=0]" to pipe stderr of the left to stdin of the right
(you can leave off the '=0', as this is implied).
Icarus Sparry

2007-08-31, 1:19 pm

On Thu, 30 Aug 2007 07:53:45 -0700, Frederic Mayot wrote:

> On Aug 29, 7:16 pm, Icarus Sparry <use...@icarus.freeuk.com> wrote:
>
> Oh sorry, I thougth it was obvious.
> appA.stderr --> appC.stdin
> appA.stdout --> appB.stdin


OK, that helps. A difficulty with the pipe notation is that it is very
linear. You could make a good case for appA | appB 2| appC to mean sending
the stderr of appB to stdin of appC.

Here is how I would do it for a simple command

(Superceeded, to correct a small error)

#!/bin/sh
# Make some alternative names for the overall stdout and stderr
exec 3>&1 4>&2
# we now start a group of commands
{
# we start appA as normal, feeding its stdout to appB
# appB has itsstdout and stderr sent to the original places
appA | appB 2>&4 1>&3
# We send any remaining stderr (which can only come from appA, as appB's
# stderr is redirected) to the stdin of appC
} 2>&1 | appC

If we are doing this for a production script then you should add 3>&- and
4>&- in 3 places so extra open file descriptors are not passed to the
programs.

The "rc" shell by Tom Duff has a much nicer syntax for much of this. You
can specify "|[2=0]" to pipe stderr of the left to stdin of the right (you
can leave off the '=0', as this is implied).

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2009 webservertalk.com