Буфер слоев ввода / вывода по умолчанию в Perl, и по умолчанию его не используют stdio
, поэтому unbuffer
и stdbuf
(которые изменяют stdio
буферизацию по умолчанию ) не работают.
Perl предоставляет свой собственный способ управления используемыми уровнями ввода-вывода: PERLIO
Переменная окружения. За в man perlrun
документации, должна быть возможность запускать set PERLIO=:unix
перед запуском команды, или для сырых родной Windows, обрабатывать на основе ввода / вывода, которые все еще могут быть экспериментальным / глючит, set PERLIO=:win32
. Либо следует обойти нормальное поведение буферизации, перейдя прямо к необработанным системным вызовам.
Если предположить, что cat
сам по себе небуферизован (я полагаю, что он использует необработанные операции чтения и записи без буферизации, так и должно быть), это все равно не гарантирует желаемого поведения. Perl может отправить данные cat
немедленно, но если не cat
удастся прочитать их и выписать обратно быстрее, чем Perl сможет перейти к следующей строке и распечатать STDERR
, вы все равно STDERR
сначала увидите вывод. В локальных тестах (в Linux, но они должны быть очень похожими) с помощью PERLIO=:unix
piping to cat
я увидел следующие результаты:
222111 333
затем:
222 111 333
затем:
111222 333
затем (дважды подряд):
111 222 333
Дело в том, что даже при буферизации вне уравнения трубопровод вводит условия гонки из-за параллелизма на уровне процесса. Единственный способ обойти это - убедиться, что оба потока идут cat
:
perl -E "say STDOUT 111; say STDERR 222; say STDOUT 333;" 2>&1 | cat
последовательно выводит:
111 222 333
потому что все данные отправляются cat
непосредственно перед выполнением следующего print
. Единственный другой способ получить (в основном) надежный заказ - это спать между отпечатками (что позволяет cat
выиграть гонку perl
).