首先让我解释一下我想要实现的目标。基本上有两个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");
}
@ {$ 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子例程将返回1(例如,如果它检测到范围之间的任何内容,则将返回1,文件系统使用百分比,默认值为100%第二个论点)。
所以这就是它变得奇怪的地方......
例如,如果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
,并且它也是这样做的。出于某种原因,我有一种印象,那就是我很想念的东西......
答案 0 :(得分:10)
这是已定义的行为。
http://perldoc.perl.org/functions/system.html
返回值是退出状态 等待返回的程序 呼叫。要获得实际退出值, 向右移动八(见下文)。
返回值-1表示无法启动程序或wait(2)系统调用错误(检查$!,原因)。