首先让我解释一下我要完成的任务。本质上有两个 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
尝试过这个,它也是一样的。出于某种原因,我的印象是我遗漏了一些非常明显的东西......
最佳答案
这是定义的行为。
http://perldoc.perl.org/functions/system.html
The return value is the exit status of the program as returned by the wait call. To get the actual exit value, shift right by eight (see below).
Return value of -1 indicates a failure to start the program or an error of the wait(2) system call (inspect $! for the reason).
关于perl - 为什么Perl的系统返回值不是我期望的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3882677/