Perl: Übergeben Sie ein Byte plus STDIN an einen anderen Befehl

8

Ich möchte das effizient machen:

%Vor%

Die Aufgabe besteht darin, wc nur zu starten, wenn eine Eingabe erfolgt. Wenn keine Eingabe erfolgt, sollte das Programm einfach beendet werden.

wc ist nur ein Beispiel hier. Es wird durch einen viel komplexeren Befehl ersetzt.

Die Eingabe kann aus mehreren TB Daten bestehen, also möchte ich wirklich diese Daten überhaupt nicht berühren (nicht einmal mit sysread ). Ich habe es versucht:

%Vor%

Aber das funktioniert nicht. Gibt es eine andere Möglichkeit, dass ich OUT sagen kann, dass, nachdem es das erste Byte bekommen hat, es gerade von STDIN lesen sollte? Vielleicht einige offene ("& gt; = & amp; 2") Gymnastik kombiniert mit exec ?

    
Ole Tange 15.04.2015, 22:04
quelle

3 Antworten

6

Das Fionread ioctl, das im Perl Cookbook erwähnt wird, kann Ihnen sagen, wie viele Bytes für einen Dateideskriptor ausstehen, ohne sie zu verbrauchen. In Bezug auf die Begriffe:

%Vor%

Dies sollte für UNIX- und UNIX-ähnliche Plattformen sehr portabel sein.

    
pilcrow 16.04.2015, 14:57
quelle
1

Ein untergeordneter Prozess erhält immer Duplikate der Datei-Handles seiner Eltern. Wenn Sie also einfach wc - entweder mit Backticks oder mit einem Aufruf von system oder exec - beginnen, liest er von der gleichen Stelle wie die % Co_de% des Perl-Prozesses.

Wenn Sie STDIN nur dann starten, wenn etwas zu lesen ist, müssen Sie wc eingeben , mit dem Sie entweder überprüfen können, ob ein Datei-Handle etwas zu lesen hat oder blockieren, bis etwas hat.

Dieses Programm überprüft, ob IO::Select Daten wartet, und führt STDIN aus und druckt seine Ausgabe, falls dies der Fall ist.

%Vor%

Der Parameter für wc ist ein Timeout in Sekunden. Wenn Sie einen Wert von Null übergeben, wird der Wert sofort zurückgegeben, wobei true zurückgegeben wird (falls tatsächlich Daten vorhanden sind) oder false ( can_read ) .

Wenn Sie keinen Parameter übergeben, wartet undef auf immer, bis etwas zu lesen ist. Sie können also Ihr Programm anhalten und auf Daten für can_read warten, indem Sie nur

schreiben %Vor%

oder Sie könnten die Konstruktion des Objekts kombinieren, um es noch prägnanter zu gestalten

%Vor%

Beachten Sie auch, dass wc auch mit Dateideskriptoren funktioniert, und da das Fileno für IO::Select Null ist, könnten Sie

schreiben %Vor%

aber das ist nicht sehr beschreibend und würde einen Kommentar benötigen, um Sinn zu ergeben

    
Borodin 16.04.2015 04:53
quelle
1

Die spezifische Lösung, an der Sie interessiert sind, ist unmöglich.

Wie Sie sicherlich schon herausgefunden haben, können Sie nicht feststellen, ob ein Datei-Handle EOF erreicht hat, ohne von ihm gelesen zu haben. [Anscheinend du kannst ] select(2) wird dich näher bringen. Es wird Ihnen sagen, dass ein Handle EOF erreicht hat oder Daten warten, aber es wird Ihnen nicht sagen, welche. Deshalb suchen Sie nach alternativen Lösungen. Leider ist der, den du gerade betrachtest, genauso unmöglich.

  

Gibt es eine andere Möglichkeit, dass ich OUT sagen kann, dass es, nachdem es das erste Byte bekommen hat, es einfach von STDIN lesen sollte?

Nein. OUT ist kein Code; es liest nichts. Es ist eine Variable. Außerdem ist es eine Variable im Elternteil. Das Ändern einer Variablen im übergeordneten Element wirkt sich nicht auf das untergeordnete Element aus.

Vielleicht wollten Sie fragen: Kann man dem Kindprogramm sagen, dass es mit einem zweiten Handle beginnt?

Nein, allgemein gesprochen. Sie können die Variablen eines anderen Programms nicht bearbeiten. Das Programm müsste speziell geschrieben werden, um zwei Dateigriffe zu akzeptieren und nacheinander zu lesen.

Andererseits ist es möglich, einen Dateinamen für ein beliebiges Datei-Handle zu erhalten, also brauchen wir nur ein Programm, das speziell dafür geschrieben ist, zwei Dateinamen zu akzeptieren und nacheinander zu lesen, und das ist ziemlich üblich.

%Vor%

(Es sind viele Fehlerüberprüfungen erforderlich.)

Oben wurde cat als Beispiel für die Verwendung Ihres Programms verwendet, stellt aber eine andere Lösung dar: Warum nicht einfach cat verwenden? Der Overhead von cat sollte für ein E / A-gebundenes Programm ziemlich gering sein.

%Vor%     
ikegami 15.04.2015 22:22
quelle

Tags und Links