As a side note, some shells have started implementing a shorthand for `foo 2>&1 | grep` which is `foo |& grep`.
As a side note, some shells have started implementing a shorthand for `foo 2>&1 | grep` which is `foo |& grep`.
(To be fair, that does seem like a pretty rare use case.)
foo 2>&1 >&- | grep ...
then you will grep only the stderr. The stdout will be discarded.Alternatively, if you only want to grep to see the stderr, but you still want to see stdout, you can swap stderr and stdout like this:
foo 3>&2 2>&1 1>&3 | grep ...
And in many shells, you can easily split the stdout and stderr into two separate pipelines like this: foo > >(grep stdout) 2> >(grep stderr)You mean this:
`foo 3>&1 1>&2 2>&3`
The above swaps stdout and stderr, saving + restoring the original stdout through descriptor 3. Shell redirection expressions map directly to dup2 syscalls, except the operands are reversed: 3>&1 is dup2(1, 3). Pipes map fairly simply to fork + exec. At its core the shell is a rather thin wrapper around the core Unix syscalls fork, exec, dup2, open, and close. If you look at the original shell implementation, the command parser more-or-less executes these syscalls as it goes along, left to right.