Frage

Ist es möglich, einen externen Prozess von Perl, erfassen seine stderr, stdout und den Prozess-Exit-Code ausgeführt werden?

ich scheinen in der Lage zu sein, Kombinationen von diesen zu tun, zum Beispiel verwenden Backticks zu stdout bekommen, IPC :: Open3 Ausgaben zu erfassen und system () Exit-Codes zu erhalten.

Wie fängt man stderr, stdout und den Exit-Code auf einmal?

War es hilfreich?

Lösung

Wenn Sie die Dokumentation für IPC :: Open3 nachzulesen, werden Sie eine Notiz sehen, die Sie aufrufen sollte waitpid das Kind Prozess zu ernten. Sobald Sie dies tun, sollte der Status in $? zur Verfügung. Der Austrittswert ist $? >> 8. Sehen $? in perldoc perlvar .

Andere Tipps

( Aktualisieren :. Ich die API für IO :: CaptureOutput aktualisiert, um diese noch einfacher zu machen)

Es gibt mehrere Möglichkeiten, dies zu tun. Hier ist eine Option, mit der IO :: CaptureOutput Modul:

use IO::CaptureOutput qw/capture_exec/;

my ($stdout, $stderr, $success, $exit_code) = capture_exec( @cmd );

Dies ist der capture_exec () -Funktion, aber IO :: CaptureOutput hat auch eine allgemeinere capture () Funktion, die verwendet werden kann, um entweder Perl Ausgang oder Ausgabe von externen Programmen zu erfassen. Also, wenn einige Perl-Modul einige externe Programm zu verwenden, geschieht, können Sie immer noch die Ausgabe erhalten.

Es bedeutet auch, brauchen Sie nur einen einzigen Ansatz zu erinnern, STDOUT und STDERR zu erfassen (oder ihre Zusammenlegung) anstelle von IPC :: Open3 für externe Programme und andere Module für die Erfassung Perl Ausgabe.

Wenn Sie nicht möchten, dass die Inhalte von STDERR, dann ist die Erfassung () Befehl von IPC :: Run3 eine saubere und einfache Schnittstelle in Re-Sanitär bietet alle drei gemeinsame Dateihandies, aber leider ist es nicht überprüfen, um zu sehen, ob der Befehl erfolgreich war, so dass Sie $ überprüfen müssen? manuell, das ist überhaupt nicht lustig. Die Bereitstellung eine öffentliche Schnittstelle für $ Inspektion? etwas ist, was auf meinem to-do-Liste für IPC: : System :: Simple, da $ Inspektion? Art und Weise in einer Cross-Plattform ist keine Aufgabe, die ich auf jemand wünschen würde.

Es gibt auch andere Module in der IPC :: Namespace dass können Sie auch mit Hilfe leisten. YMMV.

Alles Gute,

Paul

Es gibt drei grundlegende Arten von laufenden externen Kommandos:

system $cmd;        # using system()
$output = `$cmd`;       # using backticks (``)
open (PIPE, "cmd |");   # using open()

Mit system() sowohl STDOUT und STDERR den gleichen Platz wie die STDOUT Skript gehen und STDERR, es sei denn, der system() Befehl ihnen umleitet. Backticks und open() nur die STDOUT Ihres Befehl lesen.

Sie können auch so etwas wie die folgenden mit offenem rufen sowohl STDOUT und STDERR zu umleiten.

open(PIPE, "cmd 2>&1 |");

Der Rückgabecode wird immer in $? gespeichert wie bereits von @ Michael Carman .

Wenn Sie wirklich kompliziert bekommen, möchten Sie vielleicht Expect.pm versuchen. Aber das ist wahrscheinlich übertrieben, wenn Sie auch nicht Eingang als auch an den Prozess zu senden müssen verwalten.

Ich fand IPC: run3 als sehr hilfreich. Sie können alle Kind Rohre mit einem Glob oder eine Variable übermitteln; sehr leicht! Und Code Ausgang wird in $ ?. gespeichert werden

Im Folgenden ist, wie ich Stderr packte die ich eine Reihe wusste wäre. Die cmd Ausgabe informatischen Transformationen auf stdout (was ich in dem args in eine Datei geleitet mit>) und berichten, wie viele Transformationen STDERR.

use IPC::Run3

my $number;
my $run = run3("cmd arg1 arg2 >output_file",\undef, \undef, \$number);
die "Command failed: $!" unless ($run && $? == 0);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top