为什么Perl系统的返回值不符合我的预期?

w3b*_*ard 2 perl exit-code

首先让我解释一下我想要实现的目标.基本上有两个Perl脚本.一个是我用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");
Run Code Online (Sandbox Code Playgroud)

}

@ {$ 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.
Run Code Online (Sandbox Code Playgroud)

这是它变得奇怪的地方.我有一个脚本来检查文件系统的使用情况.检查完毕后,它将以适当的值退出,以便处理主脚本.

0 is Ok
1 is Warning
2 is Alert
3 is Warning + Alert
Run Code Online (Sandbox Code Playgroud)

以下是文件系统检查脚本的相关部分:

    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;
Run Code Online (Sandbox Code Playgroud)

如果在放入的两个参数的范围之间有任何内容,check_hdd子例程将返回1(例如,如果它检测到范围之间的任何内容,则将返回1,文件系统使用百分比,第二个参数的默认值为100%) ).

所以这就是它变得奇怪的地方......

例如,如果hdd脚本返回1.主脚本将显示256.

所以我进入了hdd脚本并强制它返回256.

exit 256;
Run Code Online (Sandbox Code Playgroud)

主脚本看到:0.所以我用各种值做了这个并构建了一个小表.

HDD_Check Exit Value            Main is seeing Exit Value as
         1                                    256
         256                                    0
         257                                  256
         258                                  512
         259                                  768
Run Code Online (Sandbox Code Playgroud)

啊.耐人寻味.让我们把它转换成二进制.

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

奇怪的.看起来它在传递值时执行以下操作:

return_value = return_value << 8
Run Code Online (Sandbox Code Playgroud)

那么现在已经完成了冗长的解释,任何人都有任何想法?我也试过这个die而不是exit它也是如此.出于某种原因,我有一种印象,这是我很想念的东西......

Mat*_*son 10

这是定义的行为.

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

返回值是等待调用返回的程序的退出状态.要获得实际退出值,请向右移动八(见下文).

返回值-1表示无法启动程序或wait(2)系统调用错误(检查$!,原因).