Сохраните stdout и stderr в файле, затем заново создайте вывод позже

Я перенаправил вывод в файл следующим образом:

$ ./test.bash 2> >(sed 's/^/stderr: /' >> output) > >(sed 's/^/stdout: /' >> output) $ cat output stdout: Hello World! stderr: error 

Я хотел бы точно воспроизвести вывод исходной команды ./test.bash . Вот что я пробовал:

 $ cat output | tee >(grep '^stdout: '|sed 's/^stdout: //') >(grep '^stderr: '|sed 's/^stderr: //' 1>&2) >/dev/null 2>&1 | cat error Hello World! 

Очевидно, я хотел бы, чтобы результат был в правильном порядке. Каков наилучший способ сделать это?

3 Solutions collect form web for “Сохраните stdout и stderr в файле, затем заново создайте вывод позже”

Вероятно, в зависимости от вашего текущего файла:

 awk ' /^stdout:/ { print substr($0, 9) } /^stderr:/ { print substr($0, 9) > "/dev/stderr" } ' output 

Это может стать немного более элегантным с некоторыми изменениями в вашем «сценарии записи».

если ваш test.bash выглядит так:

 echo "Hello World!"; echo error >&2 

этот скрипт loop.sh :

 ./test.bash &> original ; echo original: ; cat original; ok=0 ; er=0 for i in {1..100}; do rm output ; printf "(ok%d:er%d) running again: " $ok $er ./test.bash 2> >(cat >>output) > >(cat >>output) #<-EXAMINED COMMAND if diff output original >/dev/null; then printf "result equal...."; ((ok++)) else printf "result DIFFERENT"; ((er++)); fi done 

должен доказать, что выходной файл часто ошибочно заказывается (~ 37% в моем тесте)

Проблема связана с параллельными процессами, неконтролируемой буферизацией перенаправления и скоростью выполнения.

Решение с помощью инструмента «unbuffer» из пакета «ожидать» (если вы можете его установить). С помощью:

 (sleep 0.01 ; unbuffer ./test.bash) 

вместо того, чтобы просто ./test.bash в 4-й строке вышеприведенного скрипта, сделают идеальный (0% ошибок).

Если все ваши строки ввода начинаются с stderr: или stdout: вы можете сделать:

 perl -ne 's/^std(...):\s*//; $1 eq "err" ? print STDERR : print' output 

Или, с последними версиями bash

 while read -r out line; do [[ $out =~ ^stderr ]] && echo "$line" >&2 || echo "$line" done < output 
  • Монтирование файловой системы exFAT как пользователя без указания / dev / sdX1 в / etc / fstab
  • Совместное использование сетевого диска между Linux и Windows
  • Multipath для логического тома в промежуточной виртуальной машине
  • Портативный Linux с шифрованием дисков: какой тип хранилища лучше? SD-CARD или USB-STICK
  • Производительность `tar -xf` (размер блока)
  • Почему в пуле хранения нет потерянного + найденного каталога?
  • Как изменить размер разделов на полный образ жесткого диска?
  • Установите карту SD через USB?
  • Рекомендация для пула накопителей usb
  • Можем ли мы создать группу томов lvm с отображенным устройством?
  • Разрешение отклонено при попытке доступа к установленным окнам NFS
  • Linux и Unix - лучшая ОС в мире.