For testing purposes, I would like to save stdout and stderr separately for inspection by subsequent code. For example, a test run with erroneous input should result in output to stderr, but nothing on stdout, while a test run with correct input should result in output to stdout, but nothing to stderr. The saving has to be synchronous, to avoid race conditions with the tests (so I can't use process substitution).
To be able to debug the test after the fact, I also need to see stdout and stderr in the sequence they were output. So I have to either save them both to the same file/variable/whatever or send them to the terminal at the same time as saving them separately.
To test which error happened, I also need the exit code of the command.
For reasons of efficiency and accuracy, I of course cannot run each test twice.
Is it for example possible to redirect stdout to stdout.log, stderr to stderr.log, and both of them to output.log in the same command? Or to use a synchronous tee
command separately for stdout and stderr? Or to save a copy of stdout and stderr to separate variables?
Update: It looks like tim's solution almost works (modified to output on terminal instead of logging to all.log):
$ set -o pipefail
$ {
{
echo foo | tee stdout.log 2>&3 3>&-
} 2>&1 >&4 4>&- | tee stderr.log 2>&3 3>&-
} 3>&2 4>&1
foo
$ cat stdout.log
foo
$ cat stderr.log
$ {
{
echo foo >&2 | tee stdout.log 2>&3 3>&-
} 2>&1 >&4 4>&- | tee stderr.log 2>&3 3>&-
} 3>&2 4>&1
foo
$ cat stdout.log
$ cat stderr.log
foo
$ bar=$({
{
echo foo | tee stdout.log 2>&3 3>&-
} 2>&1 >&4 4>&- | tee stderr.log 2>&3 3>&-
} 3>&2 4>&1)
$ echo "$bar"
foo
$ cat stdout.log
foo
$ cat stderr.log
$ bar=$({
{
echo foo >&2 | tee stdout.log 2>&3 3>&-
} 2>&1 >&4 4>&- | tee stderr.log 2>&3 3>&-
} 3>&2 4>&1)
$ cat stdout.log
$ cat stderr.log
foo
$ echo "$bar"
foo
This seems to work except for the last iteration, where the value of bar
is set to the contents of stderr. Any suggestions for all of these to work?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…