【问题标题】:Why to shift bits "$? >> 8" when using Perl system function to execute command使用Perl系统函数执行命令时为什么要移位“$?>> 8”位
【发布时间】:2016-06-30 15:54:57
【问题描述】:

我在 Perl 脚本的很多地方都看到过这种情况:

system("binary");
$exit_code = ($? >> 8)
exit($exit_code)
  1. 我为什么要使用这个?有其他方法吗?

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

【问题讨论】:

  • 你为什么开始使用移位?它已经在那里了吗?你是从什么地方拿的吗?
  • 您实际上观察到的值是 134?下面的答案表明这不应该发生。
  • @T.J.Crowder 看起来 $status 没有设置...
  • @TomFenech:我想知道$?(在标题中)与$status(在代码中)的事情,但我不太了解(阅读:基本上什么) Perl...
  • Sry 实际上是 $?不是 $status @T.J.Crowder

标签: perl shell


【解决方案1】:

perldoc -f systemsn-p:

返回值是程序的退出状态 由wait 调用返回。要获得实际 退出值除以 256。

您可以通过以下方式检查所有失败的可能性 像这样检查$?

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

【讨论】:

  • 所以我的断言 (134) 也是失败之一,那么为什么通过执行 >>8 使其变为 0 ?
  • 你能描述一下等待电话吗?这是什么?
  • 等待,waitpid,waitid - 等待进程改变状态。您可以使用 man 2 wait 获得更多详细信息。
【解决方案2】:

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

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

或者,您可以在通话后单独查看$?。如果为真(非零),那仅意味着除了应用程序干净退出之外还有其他问题,或者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 上搜索。

【讨论】:

  • 是的,我知道修复的解决方案,我将删除移位来解决它,但是我需要一个正当的理由何时使用 system() 移位以及何时不使用?
  • 你说的确实有道理我发现了一些东西,system() 函数返回两个数字值合二为一。第一个是终止命令的 Unix 信号(例如 INT=2、QUIT=3、KILL=9),如果有的话。这存储在返回的低八位中。接下来的高八位包含您执行的命令的退出代码。
  • @Dipal 是的!这才是重点。即使程序刚刚返回一个零,操作系统也知道出了问题(信号)并返回给 Perl 一个非零。
  • 是的,断言是一个终止条件,所以它进入了低 8 位并且没有错误代码,所以高 8 位是 0。我现在是吗?
  • @Dipak 不错。现在,Perl 中有其他工具可以做到这一点。如果没有别的,那就是使它更容易和更清洁的模块。我没有足够用它们来推荐,但是有很多关于 SO 的好建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-02
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-14
相关资源
最近更新 更多