2 Stimmen

Warum ist der Rückgabewert des Perl-Systems nicht das, was ich erwarte?

Lassen Sie mich zunächst erläutern, was ich zu erreichen versuche. Im Wesentlichen gibt es zwei Perl-Skripte. Das eine nenne ich das Hauptskript mit einer Benutzeroberfläche. Der Benutzer, der dieses Skript ausführt, sieht eine Liste von anderen Skripten, die er über das Menü aufrufen kann. Diese Liste wird über eine benutzerdefinierte Konfigurationsdatei geladen. Der Zweck des Hauptskripts besteht darin, in Zukunft bei Bedarf weitere Skripte hinzufügen zu können, ohne den Quellcode zu ändern, und entweder als Cron-Job (nicht interaktiver Modus) oder nach Bedarf des Benutzers (interaktiver Modus) ausgeführt zu werden. Da ich aufgrund der Firmenpolitik nicht berechtigt bin, das gesamte Skript zu veröffentlichen, werde ich den Abschnitt für die Benutzerauswahl im interaktiven Modus veröffentlichen:

for($i = 0;$i < @{$conf}+1;$i++)
    {
        if($i % 2 == 1 || $i == 0)
        {
            next;
        }
        print $n++ . ". @{$conf}[$i-1]\n";
    }
    print "(health_check) ";

    #
    # User selection
    #

    my $in = <>;
    chomp($in);

    if($in =~ /[A-Za-z]/)
    {
        write_log("[*] Invalid Selection: $in");
        print "\n<<<<<<<<<<<<>>>>>>>>>>>>>\n";
        print ">>> Invalid Selection <<<\n";
        print "<<<<<<<<<<<<>>>>>>>>>>>>>\n";
    }
    elsif($in == 0)
    {
        write_log("Exiting interactive mode");
        last;
    }
    elsif(scalar($scripts[$in]))
    {
        write_log("[*] running: $scripts[$in]");
        $rez = system('./' . "$scripts[$in]");

        if($rez == 0b00)
        {
            printf("%s: [OK]\n",$scripts[$in]);
        }
        elsif($rez == 0b01)
        {
            printf("%s: [WARNING]\n",$scripts[$in]);
        }
        elsif($rez == 0b11)
        {
            printf("%s: [NOT OK]\n",$scripts[$in]);
        }
        else
        {
            print "UNKOWN ERROR CODE: $rez\n";
        }
    }
    else
    {
        write_log("[*] Invalid Selection: $in");
        print "\n<<<<<<<<<<<<>>>>>>>>>>>>>\n";
        print ">>> Invalid Selection <<<\n";
        print "<<<<<<<<<<<<>>>>>>>>>>>>>\n";    
    }

    print "\n\nPress return/enter to continue...";
    <>;
}

write_log("Exiting interactive mode");

}

@{$conf} ist ein Verweis auf die Liste der verfügbaren Skripte. Sie enthält sowohl den Namen des Skripts als auch den Pfad zum Skript.

$i is used for looping.
$n is the script number which is used for the user to select which script to run.
$in is the user input in decimal value to select which script to run.
$scripts is the actual name of the script and not the path to the script.
$rez is the return code from the scripts.

Jetzt wird es seltsam. Ich habe ein Skript, das die Nutzung des Dateisystems überprüft. Sobald dies überprüft wurde, wird es mit dem entsprechenden Wert für das Hauptskript beendet.

0 is Ok
1 is Warning
2 is Alert
3 is Warning + Alert

Hier ist der relevante Teil des Skripts für die Dateisystemprüfung:

    if(check_hdd($warning_lvl, $alert_lvl))
{
    $return_val = $return_val | 0b01;
}

if(check_hdd($alert_lvl))
{
    $return_val = $return_val | 0b10;
}

exit $return_val;

Das Unterprogramm check_hdd gibt 1 zurück, wenn irgendetwas zwischen den beiden Argumenten liegt, die eingegeben wurden (z. B. gibt es 1 zurück, wenn es irgendetwas zwischen dem Bereich der Dateisystemnutzung in Prozent mit einem Standardwert von 100 % für das zweite Argument entdeckt).

Und jetzt wird es seltsam...

Wenn zum Beispiel das Skript hdd den Wert 1. Das Hauptskript sieht 256.

Also habe ich das Skript hdd so eingestellt, dass es 256 zurückgibt.

exit 256;

Hauptdrehbuch sah: 0. Also habe ich das mit verschiedenen Werten gemacht und eine kleine Tabelle erstellt.

HDD_Check Exit Value            Main is seeing Exit Value as
         1                                    256
         256                                    0
         257                                  256
         258                                  512
         259                                  768

Ahh. Faszinierend. Konvertieren wir das in Binär.

HDD_Check Exit Value (Base 2)       Main is seeing Exit Value as (Base 2)
         0b0000000001                             0b0100000000
         0b0100000000                             0b0000000000
         0b0100000001                             0b0100000000
         0b0100000010                             0b1000000000
         0b0100000011                             0b1100000000

Seltsam. Sieht aus wie seine tun das folgende während der Übergabe des Wertes:

return_value = return_value << 8

Nun, da die langatmige Erklärung beendet ist, hat jemand eine Idee? Ich habe dies auch versucht mit die 代わりに exit und er tut dasselbe. Und aus irgendeinem Grund habe ich den Eindruck, dass es etwas sehr Offensichtliches ist, das ich übersehe...

10voto

Matthew Wilson Punkte 3761

Dies ist das festgelegte Verhalten.

http://perldoc.perl.org/functions/system.html

Der Rückgabewert ist der Exit-Status von des Programms, wie er durch den Aufruf wait Aufruf zurückgegeben wird. Um den tatsächlichen Exit-Wert zu erhalten, um acht nach rechts schieben (siehe unten).

Der Rückgabewert -1 zeigt an, dass das Programm nicht gestartet werden konnte oder dass der Systemaufruf wait(2) fehlgeschlagen ist (siehe $! für den Grund).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X