2

私が達成しようとしていることを説明することから始めましょう。基本的に、2 つの Perl スクリプトがあります。1 つは、私が UI 付きのメイン スクリプトと呼んでいるものです。このスクリプトを実行するユーザーには、メニューから呼び出すことができる他のスクリプトのリストが表示されます。このリストは、カスタム構成ファイルを介してロードされます。メイン スクリプトの目的は、ソースを変更せずに必要に応じて将来的に他のスクリプトを追加し、cron ジョブ (非対話モード) またはユーザーの必要に応じて (対話モード) 実行できるようにすることです。会社の方針として、スクリプト全体を投稿する資格はないため、インタラクティブ モードのユーザー選択セクションを投稿します。

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} は、使用可能なスクリプトのリストへの参照です。スクリプトの名前とスクリプトへのパスの両方が含まれています。

$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.

ここが奇妙になるところです。ファイルシステムの使用状況をチェックするスクリプトがあります。それがチェックされると、メイン スクリプトが処理する適切な値で終了します。

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

ファイルシステム チェック スクリプトの関連部分は次のとおりです。

    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;

check_hdd サブルーチンは、入力された 2 つの引数の範囲内に何かがある場合に 1 を返します (たとえば、範囲内に何かが検出された場合は 1 を返します)。 )。

だから、ここが変なところです...

たとえば、hdd スクリプトが 1 を返した場合、メイン スクリプトには 256 が表示されます。

そこで、hdd スクリプトを実行して、強制的に 256 を返しました。

exit 256;

メイン スクリプトは 0 を見たので、さまざまな値でこれを行い、小さなテーブルを作成しました。

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

ああ。興味深い。それをバイナリに変換しましょう。

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

変。値を渡しながら次のことを行っているようです:

return_value = return_value << 8

長い説明が終わったので、誰かわかりますか?これもdie代わりに試してみましexitたが、同じです。そして、何らかの理由で、私が見逃しているのは非常に明白なものであるという印象を持っています...

4

1 に答える 1

10

これは定義された動作です。

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

戻り値は、wait 呼び出しによって返されるプログラムの終了ステータスです。実際の終了値を取得するには、右に 8 シフトします (以下を参照)。

-1 の戻り値は、プログラムの開始に失敗したか、wait(2) システム コールのエラーを示します (理由については $! を調べてください)。

于 2010-10-07T14:31:26.447 に答える