При наличии сторонней программы, как можно одновременно:
Вот тестовая программа (delayed_interleaved_stdout_stderr.pl), которую я использовал:
#!/usr/bin/env perl
use strict;
use warnings;
# fixme: debug, uncomment to force stdout flushing
# use English '-no_match_vars';
# $OUTPUT_AUTOFLUSH = 1;
# use sleeps to simulate delays and test buffering
use Time::HiRes 'sleep';
foreach my $num ( 0..9 ) {
if ( 0 == $num % 2 ) {
print STDOUT $num, ":stdout\n";
}
else {
print STDERR $num, ":stderr\n";
}
sleep 0.25;
}
До сих пор я мог сделать 1,2,3 с:
( set -o pipefail; \
( set -o pipefail; delayed_interleaved_stdout_stderr.pl \
| tee z.stdout; exit $? \
) 3>&1 1>&2 2>&3 | tee z.stderr; exit $? \
) 3>&1 1>&2 2>&3
Благодаря ответу от lhunath и друга я упростил его до:
delayed_interleaved_stdout_stderr.pl > >(tee z.stdout) 2> >(tee z.stderr >&2)
Однако мне не удалось получить правильный порядок чередования. stderr печатает немедленно, а весь стандартный вывод (предположительно буферизованный) выводит в конце.
1:stderr
3:stderr
5:stderr
7:stderr
9:stderr
0:stdout
2:stdout
4:stdout
6:stdout
8:stdout
Запуск delayed_interleaved_stdout_stderr.pl сам по себе отображается в правильном порядке от 0 до 9. Принудительная очистка stdout работает надлежащим образом (см. Прокомментированный раздел fixme), но я не смогу изменить реальные файлы.
Может быть, мне не хватает чего-то базового, и я начинаю задаваться вопросом, возможно ли это вообще: (