Pipe stderr to file and screen without redirecting stderr to stdout

2

In a bash script I'd like to execute a command while piping the stderr to both a file and to the terminal. However, I want stderr to stay on the '2' file descriptor so that I can parse it from an external process that is calling this bash script.

All the solutions I've seen so far involve swapping stdout with stderr and then tee'ing to another file, for example:

find /var/log 3>&1 1>&2 2>&3 | foo.file

If I am to call this script from another one, the stderr will go to stdout and stdout will go to stderr, which is no good for me. I've tried to swap them again like so:

find /var/log 3>&1 1>&2 2>&3 | foo.file 4>&1 1>&2 2>&4

but this doesn't work.

Eddy

Posted 2018-09-25T10:14:47.693

Reputation: 2 897

Answers

3

I found out how to do it in the end, following advice from this page. I need to redirect stderr to tee then redirect the output of tee back to stderr.

find /var/log 2> >(tee foo.file >&2)

Eddy

Posted 2018-09-25T10:14:47.693

Reputation: 2 897

Should work, but I would expect stdout and stderr from find to desynchronize in the terminal sometimes. This is due to tee, buffers etc. If find writes stdout and stderr directly to the same device, the issue never happens; but if the two streams are merged later, it's possible. – Kamil Maciorowski – 2018-09-25T10:40:21.980