当使用Perl系统函数执行命令时,为什么要移位“$?>> 8”

时间:2016-03-15 09:35:08

标签: perl shell

我在Perl脚本的很多地方都看到了这个:

system("binary");
$exit_code = ($? >> 8)
exit($exit_code)
  1. 我为什么要用这个?还有另一种方法吗?

  2. 我在system(binary)中调用了一些我在C ++中创建的二进制文件,它执行了一些操作,如果失败则会给assert。当我重新启动Linux机器时,正在运行的内容失败,我的二进制文件按预期生成assert。但是在我调用它的Perl端,它会抛出一个134错误代码,在134 >> 8之后变为0。最终它使我的失败操作成功(我不想要)。

2 个答案:

答案 0 :(得分:6)

perldoc -f system摘录:

  

返回值是程序的退出状态                  由wait电话返回。得到实际的                  退出值除以256.

     

您可以检查所有失败的可能性                  像这样检查$?

$exit_value  = $? >> 8;
$signal_num  = $? & 127;
$dumped_core = $? & 128;

答案 1 :(得分:3)

system下执行的程序可能会在退出时返回特定代码。它打包成高位数(退出状态),这是Perl获得的以及$?中可用的内容。这就是你要测试这个数字的原因,例如(但见下文)

system($cmd) == 0  or die "Error: $?";

或者,您可以在通话后单独检查$?。如果为true(非零),则表示应用程序除了清除退出之外还有其他内容,或者system本身存在问题。当您解压缩时,您正在寻找应用程序在退出时传达的内容。为了仅查看是否存在错误,您只需查看$?,并且 获取值。所以没有冲突。

程序返回的代码是其业务(或设计决策)。理想情况下,程序在失败时会退出代码(如果它们可以检测并处理问题),并且有文档说明代码意味着什么。有关示例,请参阅this answer,以及其他评论this one

system所示,您可以轻松获得:退出代码$? >> 8,信号编号​​$? & 127以及核心是否被转储$? & 128。退出状态为134时,信号编号​​为6man 7 signal列为SIGABRT。核心也应该在那里。这就是你从程序中得到的,没有明确的退出代码。显然,该计划导致中止和倾销核心。

在您的情况下,您知道所有这些来自何处 - assert是一个调用abort的宏,其中SIGABRT被引发(man 3 assert abort)。 Perl将6打包回134

请注意,assert会向STDERR打印一条消息,因此您可能希望通过qx(反引号)运行该程序,在这种情况下,您可以捕获该错误。请参阅上面的第一个链接,或搜索SO。

相关问题