0
votes

The "|" pipe operator connects the stdout of one process to the stdin of another. Is there any way to create a pipe that connects the stderr of one process to the stdin of another keeping the stdout alive in my terminal? Searching on the internet gave me no information at all...

Thank you in advance, Michalis.

4

4 Answers

3
votes

If you're happy to mix stdouot and stderr, then you can first redirect stderr to stdout and then pipe that:

theprogram 2>&1 | otherprogram

If you don't want stdout, you can kill that one:

theprogram 2>&1 1> /dev/null | otherprogram

If you do want to store the original stdout as well, then you have to redirect it either to a file (in place of /dev/null), or to another file descriptor that you opened previously with exec. Here are some details.

(Unfortunately there is no direct "pipe this file descriptor" syntax like 2|. That would have been handy.)

3
votes

You can get this effect with bash's process substitution feature:

somecommand 2> >(errorprocessor)
2
votes

You could use named pipes:

mkfifo /my/pipe
error-handler </my/pipe &
do-something 2>/my/pipe

This should keep stdin & stdout of "do-something" in your terminal und redirect stderr to /my/pipe, which is read by "error-handler".

(I hope this work, have no bash to test)

2
votes

You may also swap the stdout & stderr streams, i. e. stdout becomes the new stderr and stderr becomes the new stdout).

# only the stdout stream gets upcased
ls -ld / xxx ~/.bashrc yyy 3>&1 1>&2 2>&3 3>&- | tr '[[:lower:]]' '[[:upper:]]'

# block original stdout by closing fd 1
ls -ld / xxx ~/.bashrc yyy 2>&1 1>&- | tr '[[:lower:]]' '[[:upper:]]'