help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] stdout and stderr to two different process substitutions


From: Bob Proulx
Subject: Re: [Help-bash] stdout and stderr to two different process substitutions
Date: Wed, 25 Jan 2012 13:48:24 -0700
User-agent: Mutt/1.5.21 (2010-09-15)

Peng Yu wrote:
> Greg Wooledge wrote:
> > There is certainly no "global stdout".  FDs are inherited, but
> > then they can be closed or redirected.
>
> OK. I see my mistake. But I still don't understand why stdout of tee
> goes to stdout of foo, hence redirected to the stdin of gzip hence
> goes to xx.gz. This appears to be that tee and foo share the same
> stdout.

Let me try with a fuzzier but perhaps more intuitive explanation.
You have a terminal and stdin and stdout are coming to and from your
keyboard (through the tty/pty) and are hooked to the outside of the
entire blob.  In the middle of the blob are smaller blobs split at
process boundaries.  Inside each of those blobs are again smaller
blobs.  It is blobs all of the way down.  At each boundary layer you
can apply plumbing to connect stdin(fd=0), stdout(fd=1), and
stderr(fd=2) up to different pipes.

> foo > >(gzip >xx.gz) 2> >(tee yy)

Let's try some pictures (and challenge my picture drawing ability)
with some basic work flow.

  Start with the basic process flow.

             |   | --err:2-->
    --in:0-->|foo|
             |   | --out:1-->

  Apply > >(gzip >xx.gz)
    First must launch gzip with redirection.
    This is a separate process in addition to the above.

             |    | --err:2-->
    --in:0-->|gzip|
             |    | --out:1-->xx.gz

  Then apply >(list) processing attaching it to /dev/fd/63 or some
  such /dev/fd file descriptor.

  Then apply > to >(gzip >xx.gz).

             |   | --err:2-->
    --in:0-->|foo|
             |   | --out:1-->/dev/fd/63--\
                                          |
    /------------------------------------/
   |
   |                 |         |    | --err:2-->
    \-->/dev/fd/63-->|--in:0-->|gzip|
                     |         |    | --out:1-->xx.gz

  Apply 2> >(tee yy), start with tee yy first.

             |   | --err:2-->
    --in:0-->|tee|
             |   | --out:1-->yy

  Add the >(list) part.

                     |   | --err:2-->
  /dev/fd/63--in:0-->|tee|
                     |   | --out:1-->yy

  Add the 2> to it.

             |   | --err:2-->/dev/fd/62----------------\
    --in:0-->|foo|                                      \
             |   | --out:1-->/dev/fd/63--\               \
                                          |               |
    /------------------------------------/                |
   |                                                      |
   |                 |         |    | --err:2-->          |
    \-->/dev/fd/63-->|--in:0-->|gzip|                     |
                     |         |    | --out:1-->xx.gz     /
                                                         /
                                                        /
     /-------------------------------------------------/
    /
   |
   |                 |         |   | --err:2-->
    \-->/dev/fd/62-->|--in:0-->|tee|
                     |         |   | --out:1-->yy

That will either look useful or be a complete mess of ascii
characters.  Hopefully it will help.

See in the above that the in:0 input on the left is still coming into
the outermost blob as fd 0 and the err:2 output on the right it still
leaving on fd 2.  If there is an error from gzip or tee you will see
it on fd 2 stderr.  But an error from fo is piped to the gzip's fd 0
stdin file.

Normal piping is much easier.

HTH,
Bob



reply via email to

[Prev in Thread] Current Thread [Next in Thread]