【问题标题】:system() returns non-zero but still performs actionsystem() 返回非零但仍执行操作
【发布时间】:2016-01-18 23:04:58
【问题描述】:

我正在使用system 命令压缩一些日志文件:

if (system("gzip -f log.csv"))
{
      printf("gzip failed");
      return;  
}

偶尔(非常不一致),我会收到gzip failed 消息,该消息会退出函数并且不执行其他一些取决于 gzip 是否成功的任务。但是,当我在命令行中检查目录时,该文件确实被正确压缩到 log.csv.gz 中(即我可以 gunzip 它 - 即使 system 返回非零,该命令显然也没有失败值)。

这怎么可能?我只是错过了什么吗?

【问题讨论】:

  • 查看 gzip 发生时向 stderr 写入的内容。我不知道您希望我们如何在没有日志的情况下告诉您任何有用的信息。
  • ...例如,如果在操作期间有任何其他内容更改了其输入文件,您的 gzip 实现可能会以错误状态退出(因为这意味着它无法确定压缩版本与输入的任何版本完全匹配)。
  • 顺便说一句,我希望你真正的程序是硬编码日志名称(就像你在这里一样),而不是将任何任意文件名替换为 system() 调用。想想如果你有一个使用touch '$(rm -rf ~)' 创建的文件,并将该名称替换为对system() 的调用会发生什么。 (引用可以使执行一点变得更加困难,但只能通过转义来完全避免......或做正确的事情并通过适当的fork()/ exec()调用您想要的外部程序( ) 使用数组中传递的参数,并非所有参数都在一个字符串中被 shell 解析出来)。
  • this,来自system() 的手册页可能会解释您所看到的:返回的值为 -1 错误(例如,fork(2) 失败),返回状态为否则命令。后一种返回状态采用 wait(2) 中指定的格式。因此,该命令的退出代码将是 WEXITSTATUS(status)。如果 /bin/sh 无法执行,退出状态将是执行 exit(127) 的命令的状态。

标签: c linux


【解决方案1】:

根据guide,gzip 返回的退出代码为 2 意味着它有一个警告。这意味着它可能产生了输出但可能不正确?

【讨论】:

  • 其实问题又来了。请参阅下面的答案-
【解决方案2】:

绝对没有要求具有非零退出状态的程序回滚它在导致该状态的错误之前执行的所有操作。事实上,这样的行动通常要么是不可能的,要么是具有破坏性的。

因此,任何命令都完全有可能返回非零退出状态,但仍会对系统状态产生影响。

【讨论】:

  • 还有另一个选项 - 命令执行得很好,但 system() 本身返回错误。看我的回答 -
  • 嘿。如果你指明了具体的返回值,也许就可以到达那里。无论如何,很好的发现。
【解决方案3】:

我做了更多调查,似乎 gzip 失败的根本原因似乎是两个 waidpid 调用之间的竞争条件:一个在 system() 本身中,另一个在某个自定义 SIGCHLD 处理程序中代码中的 else (这是一个巨大的数千行过程)。

如果自定义 SIGCHLD 处理程序获取子 (gzip),则 system() 返回 -1(因为其 waidpid 失败),否则 system() 按预期返回 0。

这是帮助我最终解决它的 SO 帖子:

C++: system(0) Returns 0

【讨论】:

    猜你喜欢
    • 2012-06-20
    • 2018-09-07
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 2020-08-06
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多