2016-11-24 1 views
1

Ich versuche, das Perl-Modul IPC :: Run3 zu testen, aber zu überprüfen, ob ein Befehl fehlgeschlagen oder erfolgreich ist.
Ich weiß, dass IPC :: Run3 einen Exit-Code ausgibt, wenn etwas mit seinen Argumenten falsch ist, aber was ist, wenn die Argumente in Ordnung sind, aber der Befehl nicht existiert? Wie kann ich das folgende Beispiel testen?So testen Sie den Exit-Status von IPC :: Run3

Nachdem ein Unterprogramm Run3 ruft

sub runRun3 { 

    my $cmd = shift; 
    my ($stdout, $stderr); 

    run3($cmd, \undef, \$stdout, \$stderr); 

# if($? == -1) { 
    if (! $stdout and ! $stderr) { 
     die "Something is wrong"; 
    } else { 
     print "OK \n"; 
    } 

} 

wenn Befehl $cmds[0] unten ausgeführt wird (der ls Befehl von * nix-Systemen) druckt OK wie erwartet, aber mit dem Befehl $cmds[1] es sagt nur No such file or directory at ./testrun3.pl line 18. Mit einem Test auf den Exit-Code möchte ich stattdessen Something is wrong drucken.

#!/usr/bin/perl 

use warnings; 
use strict; 

use IPC::Run3; 

my @cmds = qw(ls silly); 

runRun3($cmds[0]); 
runRun3($cmds[1]); 

Oder was wäre die beste Alternative zu IPC :: Run3 in solchen Fällen? Dies ist nur eine zu starke Vereinfachung des Prozesses, aber letztendlich möchte ich STDERR und STDOUT für komplexere Situationen erfassen.

Danke.

Antwort

2

Ein paar Punkte zu durchlaufen.

Zunächst für die direkte Frage, die IPC::Run3 Dokumentation sagt uns, dass

run3 eine Ausnahme auslöst, wenn der umwickelte system Anruf -1 zurückgegeben oder irgendetwas schief gelaufen ist mit run3 ‚s Verarbeitung von Dateihandies. Sonst ist es wahr. Es lässt $? intakt für Inspektion des Ausgangs- und Wartezustandes.

Der Fehler Sie fragen, ist von dieser Art, und Sie müssen eval den Anruf, dass Ausnahme

use warnings 'all'; 
use strict; 
use feature 'say'; 

my ($stdout, $stderr); 

my @cmd = ("ls", "-l"); 

eval { run3 \@cmd, \undef, \$stdout, \$stderr }; 
if ([email protected]  ) { print "Error: [email protected]";      } 
elsif ($? & 0x7F) { say "Killed by signal ".($? & 0x7F); } 
elsif ($? >> 8 ) { say "Exited with error ".($? >> 8); } 
else    { say "Completed successfully";   } 

Sie jetzt fangen können Sie Ihre eigenen Nachrichten innerhalb if ([email protected]) { } Block drucken, wenn Fehler passieren, wo die zugrunde liegenden system kann nicht ausgeführt werden. Zum Beispiel wenn ein nicht existierendes Programm aufgerufen wird.

Hier [email protected] bezieht sich auf eval während $? bis system. Wenn also run3 kein Problem hat und [email protected] falsch ist, prüfen wir als nächstes den Status von system selbst, also $?. Von docs

Beachten Sie, dass ein echter Rückgabewert von run3 bedeutet nicht, dass der Befehl einen erfolgreichen Exit-Code hatte. Daher sollten Sie immer $? überprüfen.

Für Variablen [email protected] und $? siehe General Variables in perlvar und system und eval Seiten.

Eine minimale Version davon ist eval (und [email protected] Prüfung) und erwarten, dass das Programm zu die wenn run3 hatten Probleme fallen zu lassen, was selten sein sollte, und (und Druck) den Wert von $? zu überprüfen.

Ein Hinweis auf run3 Schnittstelle. Mit \@cmd erwartet es @cmd, um einen in Wörter gebrochenen Befehl zu enthalten, wobei das erste Element das Programm und die restlichen Argumente sind. Es besteht ein Unterschied zwischen dem Schreiben eines Befehls in einer Zeichenfolge, der von der Schnittstelle $cmd unterstützt wird, und einem Array. Eine Erläuterung finden Sie unter system.

Welche Alternative am besten zu Ihnen passt, hängt von Ihren genauen Bedürfnissen ab. Hier sind einige Optionen. Vielleicht zuerst versuchen IPC::System::Simple (aber keine STDERR auf dem Plattenteller). Für die saubere Erfassung aller Arten von Ausgabe Capture::Tiny ist großartig. Am anderen Ende gibt es IPC::Run für weit mehr Leistung.

+0

@ikegami Oh, sicher, viel besser, alles (und richtig) zu zeigen. Vielen Dank. – zdim