Wie kann ich die stdin und stdout von Systembefehl aus einem Perl-Skript erfassen?

StackOverflow https://stackoverflow.com/questions/78091

  •  09-06-2019
  •  | 
  •  

Frage

In der Mitte eines Perl-Skript gibt es einen Systembefehl Ich möchte auszuführen. Ich habe eine Zeichenfolge, die die Daten enthalten, die in stdin zugeführt werden muss (der Befehl akzeptiert nur eine Eingabe von stdin), und ich brauche die Ausgabe in stdout geschrieben zu erfassen. Ich habe bei den verschiedenen Methoden sah Systembefehle in Perl auszuführen, und die open Funktion scheint zu sein, was ich brauche, außer dass es sieht aus wie ich nur stdin oder stdout erfassen kann, nicht beide.

Im Moment, es ist wie meine beste Lösung scheint, ist open zu verwenden, stdout in eine temporäre Datei umleiten, und aus der Datei nach dem Befehl beendet lesen. Gibt es eine bessere Lösung?

War es hilfreich?

Lösung

Ich glaube, Sie einen Blick nehmen wollen unter IPC :: Open2

Andere Tipps

IPC :: Open2 / 3 sind in Ordnung, aber ich habe festgestellt, dass in der Regel alles, was ich wirklich brauchen, ist IPC :: Run3 , die die einfachen Fälle wirklich gut mit minimaler Komplexität behandelt:

use IPC::Run3;    # Exports run3() by default

run3( \@cmd, \$in, \$out, \$err );

Die Dokumentation vergleicht IPC :: Run3 zu anderen Alternativen. Es lohnt sich ein noch lesen, wenn Sie es nicht zu benutzen entscheiden.

Die perlipc Dokumentation deckt viele Möglichkeiten, wie Sie dies tun können, einschließlich IPC :: Open2 und IPC :: Open3.

Irgendwo am Anfang des Skripts, umfasst die Zeile

use IPC::Open2;

Das wird die notwendige Modul umfasst, in der Regel mit den meist Perl-Distributionen standardmäßig installiert. (Wenn Sie es nicht haben, Sie könnten es installieren CPAN verwenden.) Dann wird anstelle von offenen, Aufruf:

$pid = open2($cmd_out, $cmd_in, 'some cmd and args');

Sie können Daten auf Ihren Befehl senden, indem er auf $ CMD_IN Senden und dann Ihren Befehl die Ausgabe lesen, indem von $ cmd_out zu lesen.

Wenn Sie auch in der Lage sein wollen, den Befehl des Stderr Stream zu lesen, können Sie den IPC :: Open3 Modul stattdessen verwenden.

IPC :: Open3 würde wahrscheinlich tun, was Sie wollen. Es kann erfassen STDERR und STDOUT.

http://metacpan.org/pod/IPC::Open3

Eine sehr einfache Möglichkeit, dies zu tun, die ich ist vor kurzem gefunden IPC :: Filter Modul . Damit können Sie den Job extrem intuitiv:

$output = filter $input, 'somecmd', '--with', 'various=args', '--etc';

Beachten Sie, wie es Ihr Befehl ruft durch die Schale, ohne dabei, wenn Sie es sich um eine Liste übergeben. Es spielt auch eine angemessene Arbeit von Fehlern für gemeinsame Dienstprogramme Handhabung. (Bei einem Fehler, es dies, mit dem Text von STDERR als Fehlermeldung;. Bei Erfolg wird STDERR nur verworfen)

Natürlich ist es nicht geeignet für große Datenmengen, da es keine Möglichkeit gibt jede Streaming-Verarbeitung zu tun; Auch könnte die Fehlerbehandlung nicht granular genug für Ihre Bedürfnisse. Aber es macht die vielen einfachen Fällen wirklich wirklich einfach.

Es gibt einen speziellen Perl-Befehl für sie

open2()

Weitere Informationen finden Sie unter: http://sunsite.ualberta.ca/Documentation/Misc/perl-5.6.1/lib/IPC/Open2.html

Wenn Sie keine zusätzlichen Pakete aufnehmen möchten, können Sie einfach tun

open(TMP,">tmpfile");
print TMP  $tmpdata ;
open(RES,"$yourcommand|");
$res = "" ;
while(<RES>){
$res .= $_ ;
}

das ist das Gegenteil von dem, was Sie vorgeschlagen, soll aber auch funktionieren.

ich es auf diese Weise immer tun, wenn ich nur eine einzige Zeile ausgegeben oder will erwarte das Ergebnis auf etwas anderes als eine neue Zeile teilen:

my $result = qx( command args 2>&1 );  
my $rc=$?;  
# $rc >> 8 is the exit code of the called program.

if ($rc != 0 ) {  
    error();  
}  

Wenn Sie mit einem mehrzeiligen Antwort beschäftigen möchten, erhalten Sie das Ergebnis als Array:

my @lines = qx( command args 2>&1 );  

foreach ( my $line ) (@lines) {  
    if ( $line =~ /some pattern/ ) {  
        do_something();  
    }  
}  
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top