Der standardmäßige E / A-Layer-Puffer von Perl wird normalerweise nicht verwendet stdio
, weshalb unbuffer
und stdbuf
(welche die Standardpufferung modifizieren stdio
) nicht funktionieren.
Perl bietet jedoch eine eigene Methode zur Steuerung der verwendeten E / A-Schichten: Die PERLIO
Umgebungsvariable. Gemäß den man perlrun
Dokumenten sollte es möglich sein, set PERLIO=:unix
vor dem Ausführen des Befehls ausgeführt zu werden, oder für rohe, native Windows-Handle-basierte E / A-Operationen, die möglicherweise noch experimentell oder fehlerhaft sind set PERLIO=:win32
. Entweder sollte man das normale Pufferungsverhalten umgehen, indem man direkt zu den rohen Systemaufrufen geht.
Angenommen, sich cat
selbst ist ungepuffert (ich glaube, dass es rohe Lese- und Schreibvorgänge ohne Pufferung verwendet, so sollte es sein), dies garantiert jedoch nicht das gewünschte Verhalten. Perl könnte die Daten cat
sofort senden, aber wenn cat
es nicht gelingt, sie schneller einzulesen und zurückzuschreiben, als Perl in die nächste Zeile wechseln und drucken kann, STDERR
wird die STDERR
Ausgabe immer noch angezeigt. In lokalen Tests (unter Linux, aber es sollte ziemlich ähnlich sein) mit PERLIO=:unix
, Pipe to cat
, habe ich folgende Ausgaben gesehen:
222111 333
dann:
222 111 333
dann:
111222 333
dann (zweimal hintereinander):
111 222 333
Der Punkt ist, dass selbst bei Pufferung außerhalb der Gleichung die Rohrleitung Rennbedingungen aufgrund der Parallelität auf Prozessebene einführt. Der einzige Weg, dies zu umgehen, ist sicherzustellen, dass beide Streams zu cat
:
perl -E "say STDOUT 111; say STDERR 222; say STDOUT 333;" 2>&1 | cat
konsistent liefert:
111 222 333
weil alle Daten cat
unmittelbar vor der nächsten print
Ausführung an gesendet werden . Der einzige Weg, um (meistens) zuverlässig zu bestellen, besteht darin, zwischen den Ausdrucken zu schlafen (wodurch cat
das Rennen mit gewonnen werden kann perl
).