В целях тестирования я хотел бы сохранить stdout и stderr отдельно для проверки последующим кодом. Например, тестовый запуск с ошибочным вводом должен привести к выводу в stderr, но ничего не выводить на stdout, в то время как тестовый запуск с правильным вводом должен привести к выводу на stdout, но ничего к stderr. Сохранение должно быть синхронным, чтобы избежать гонок в тестах (поэтому я не могу использовать подстановка процесса ).
Чтобы иметь возможность отладить тест после факта, я также должен видеть stdout и stderr в той последовательности, в которой они были выведены. Поэтому мне нужно либо сохранить их оба в один и тот же файл / переменную / что угодно, либо отправить их на терминал одновременно с сохранением их отдельно.
Чтобы проверить, какая ошибка произошла, мне также нужен код завершения команды.
Из соображений эффективности и точности я, конечно, не могу выполнить каждый тест дважды.
Возможно ли, например, перенаправить stdout в stdout.log, stderr в stderr.log, и оба в output.log одной и той же командой? Или использовать синхронную tee
команду отдельно для stdout и stderr? Или сохранить копию stdout и stderr в отдельных переменных?
Обновление : Похоже, решение Тима почти работает (изменено для вывода на терминал вместо записи в 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
Кажется, это работает, за исключением последней итерации, где значение bar
установлено на содержимое stderr. Любые предложения для всего этого, чтобы работать?