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

Dip*_*pak 3 shell perl

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

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

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

sot*_*ona 6

perldoc -f system 片段:

返回值是wait调用返回的程序的退出状态.要使实际退出值除以256.

您可以通过以下方式检查所有故障可能性$?:

$exit_value  = $? >> 8;
$signal_num  = $? & 127;
$dumped_core = $? & 128;
Run Code Online (Sandbox Code Playgroud)


zdi*_*dim 6

在下执行的程序system退出时可能会返回特定的代码。那被打包成Perl获得的一个数字的高位(退出状态$?。例如,这就是为什么要测试该数字的原因(但请参见下文)

system($cmd) == 0  or die "Error: $?";
Run Code Online (Sandbox Code Playgroud)

或者,您可以单独检查$?通话后。如果为true(非零),则仅表示该应用程序存在干净退出或system自身问题之外的其他问题。拆包时,您正在寻找应用程序在其出口处传达的信息。为了仅查看是否有错误,您仅查看$?得到了一个值。因此没有冲突。

该程序返回的代码是其业务(设计决策)。理想情况下,程序会在代码失败(如果它们可以检测并处理问题)时以代码退出,并提供说明什么代码意味着什么的文档。举个例子看看这个答案,并另评论这一个

系统中可以看到,您很容易获得:退出代码$? >> 8,信号号$? & 127以及是否转储内核$? & 128。在您的退出状态下134,信号编号​​为6man 7 signal列出为SIGABRT。核心也应该在那里。这就是您从程序中获得的结果,而没有显式的退出代码。显然,该程序导致中止并丢弃了核心。

在您的情况下,您知道所有这些都来自- assert是一个调用的宏abort,由此SIGABRT引发了(man 3 assert abort)。Perl收回6打包成的文件134


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

  • 你所说的确实很有道理,我发现了一些东西,system() 函数返回两个数值合并为一个。第一个是终止命令的 Unix 信号(例如 INT=2、QUIT=3、KILL=9)(如果有)。这存储在返回的低八位中。接下来的高八位包含您执行的命令的退出代码。 (2认同)