Perl по умолчанию I/O слои буфер, и не использовать 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).