On Fri, Jan 15, 2010 at 03:25:13AM -0500, A. Costa wrote:
> After some thinking & fussing I learn STDIN can be used like a prefab
> short-term named pipe.
>
> # an 'ls' that outputs to STDERR and STDOUT
> % ls nosuchfile /bin/bash
> ls: cannot access nosuchfile: No such file or directory
> /bin/bash
>
> # run 'wc' on both separately, with no extra files or named pipes
> % { { { ls nosuchfile /bin/bash >& 0 ; } 2>&1 | wc -c 1>&2 ; } 0>&1 |
> wc -c ; } 2>&1
> 56
> 10
You can use any file descriptor you like here. While you *can* use 0
and 2 for your temporaries if they happen not to be doing anything much
else, I find it much clearer to pick unallocated and distinct ones. For
example:
{ { { ls nosuchfile /bin/bash >&3; } 2>&1 | wc -c >&4; } 3>&1 | wc -c; } 4>&1
When writing this, I find it helpful to observe that X>&Y more or less
maps to dup2(Y, X) (with some saving and restoring of the original X
thrown in), and that this can only succeed if Y was previously open.
It's then worth reading it from the outside in, since this is roughly
the order in which the shell executes it.
One thing which may not be obvious is that those two 'wc -c' commands
may be executed in parallel. It works fine with wc since it waits for
its input to be closed before producing any output, but if you use
commands there that don't have that property then you may find you get
overlapping output. sponge(1) from moreutils may be of use as an
artificial delay here (e.g. 'sponge /dev/stdout').
Cheers,
--
Colin Watson [[email protected]]
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]