Perl: Nach einem erfolgreichen Systemaufruf beendet der Befehl "or die" das Skript immer noch

9

Ich verwende die folgende Zeile, um einen einfachen Systemaufruf zu machen, der funktioniert:

%Vor%

Beim Ausführen des Skripts wird das System aufgerufen, und ich kann ein Verzeichnis namens Purged finden, aber die Fehlermeldung wird weiterhin gedruckt und das Skript stirbt ab. Was ist falsch an meiner Syntax?

Jede Hilfe wird sehr geschätzt.

    
user3481208 31.03.2014, 13:23
quelle

4 Antworten

6
  

Das wäre ein wenig verwirrend, nicht wahr? - Leonardo Herrera auf Ikegamis Antwort

Ja, es ist verwirrend, dass der system -Befehl in Perl Wahr und Falsch umkehrt und so eine lustige Logik erzeugt:

%Vor%

Aber es ist verständlich, warum der Befehl system dies tut. In Unix bedeutet ein Exit-Status von Null, dass das Programm funktioniert hat, und ein Status ungleich Null könnte Ihnen Informationen darüber geben, warum Ihr system -Aufruf fehlgeschlagen ist. Vielleicht existiert das Programm, das Sie angerufen haben, nicht. Vielleicht hat das Programm wie erwartet funktioniert. Zum Beispiel gibt grep einen Beendigungscode von 1 zurück, wenn grep funktioniert, aber es gab keine übereinstimmenden Zeilen. Sie möchten möglicherweise unterscheiden, wenn grep den Wert null, eins oder einen Rückgabecode größer als eins zurückgibt. (Ja, ich weiß, dass es albern ist, einen Systemaufruf an grep in einem Perl-Programm zu verwenden, aber das ist das erste Beispiel, das mir einfällt).

Um eine zufällige Verwirrung zu vermeiden, erstelle ich eine Variable, die den Exit-Status meines system -Befehls enthält, anstatt die Ausgabe von system direkt zu testen:

%Vor%

Es ist völlig unnötig, und Leute, die mit Perl arbeiten, sollten wissen, dass system Perls Definition von true und false umkehrt, aber wenn ich meinen Kaffee nicht gehabt hätte Am Morgen kann ich es vermissen, wenn ich über den Code von jemand anderem gehe. Durch diesen kleinen Schritt wird das Programm etwas logischer.

Das Perldoc des Systems gibt Ihnen Code, mit dem Sie die Ausgabe Ihres Systembefehls genau prüfen können Was ist passiert. (Wenn ein Fehler aufgetreten ist oder ein Systemunterbrechungssignal den Aufruf system abgebrochen hat). Es ist schön zu wissen, ob Sie Ihren system Rückgabewert abfragen müssen, um herauszufinden, was schief gelaufen ist.

    
David W. 31.03.2014, 16:00
quelle
15

system gibt den Exit-Status des von ihm aufgerufenen Befehls zurück. In der Shell bedeutet Null-Status den Erfolg. Sie müssen die Logik invertieren:

%Vor%     
choroba 31.03.2014 13:27
quelle
5

system gibt 0 bei Erfolg zurück, also möchten Sie and anstatt or .

Siehe auch: use autodie qw( system );

    
ikegami 31.03.2014 13:46
quelle
1

Hinzufügen, was nicht erwähnt wurde und was die Leute ruhig vermasseln kann.

Die system Rückgabe von 'zero-or-not' gibt nur an, ob der Befehl ausgeführt wurde , erfolgreich durch Shell oder execvp ; Daher bedeutet 0 nicht, dass der Befehl selbst erfolgreich war, was er tat .

Bei einer Rückgabe ungleich null müssen Sie für weitere Informationen $? entpacken: Der tatsächliche Beendigungscode des Befehls lautet $? >> 8 . Er enthält alles, was das ausgeführte Programm zum Beenden an seinem Ausgang entworfen hat. (Für jede Ausgabe müssen Sie qx oder verschiedene Piped-Ops anstelle von system verwenden.)

Insgesamt möchten Sie vielleicht etwas für

tun %Vor%

Dies muss natürlich nicht in einem Unterverzeichnis sein, Sie können system == 0 or do { ... }; oder ein solches Recht im Code eingeben und lediglich den Fehler mit warn ausgeben. Aber auf diese Weise haben Sie eine kleine Bibliothek, in der Sie Ihre Fehlerbehandlung leichter verfeinern können usw. Da es sich um eine Einrichtung auf Benutzerebene handelt, ist es sinnvoll, dass sie bei Erfolg als wahr zurückgeht (wir ändern das Systemdesign nicht).

Außerdem ist in diesem Fall mkdir -p still und es kann durchaus keine Fehler werfen, auch wenn es sein Ding nicht machen kann. Dies ist natürlich beabsichtigt, aber man sollte sich dessen bewusst sein.

    
zdim 21.02.2016 23:49
quelle

Tags und Links