【问题标题】:Can system() return before piped command is finishedsystem() 可以在管道命令完成之前返回吗
【发布时间】:2011-06-17 09:36:31
【问题描述】:

我在 Linux 上使用来自 libc 的 system() 时遇到问题。我的代码是这样的:

system( "tar zxvOf some.tar.gz fileToExtract | sed 's/some text to remove//' > output" );

std::string line;
int count = 0;
std::ifstream inputFile( "output" );
while( std::getline( input, line != NULL ) )
    ++count;

我反复运行这个 sn-p,偶尔我发现在运行结束时 count == 0 - 没有从文件中读取任何行。我查看了文件系统,该文件具有我期望的内容(大于零行)。

我的问题是 system() 是否应该在传入的整个命令完成时返回或者是否存在管道'|'意味着 system() 可以在管道完成后的部分命令之前返回吗?

我没有明确地使用“&”来将命令的任何部分作为 system() 的背景。

为了进一步澄清,我在实践中确实并行运行了多次代码 sn-p,但输出文件是一个以线程 ID 命名的唯一文件名,并且每次调用 system() 时都会递增一个静态整数。我确信每次调用 system() 时输出和读取的文件都是唯一的。

【问题讨论】:

  • 你有没有发现为什么 count 有时会在你认为不应该为零的情况下为零?

标签: c++ linux system libc


【解决方案1】:

根据documentation

system() 函数在子进程终止之前不会返回。

也许当它失败时捕获“输出”的输出,看看它是什么?此外,检查system 的返回值将是一个好主意。一种情况是您正在运行的 shell 命令失败并且您没有检查返回值。

【讨论】:

  • 这是个好主意,我会做的。但是我可以看到文件按预期提取,这意味着系统命令已成功完成。我的问题是为什么在 system() 调用之后尝试读取文件时文件最初是空的,然后当我查看文件系统时又是非空的。
  • 我接受了您的回答,因为它主要简洁地回答了我关于 system() 行为的问题(管道命令 do 需要在 system() 返回之前完成)。谢谢!
【解决方案2】:

system(...) 调用标准 shell 来执行命令,只有在 shell 重新获得对终端的控制后,shell 本身才应该返回。因此,如果有其中一个程序在后台运行,系统将提前返回。

后台通过使用& 为命令添加后缀发生,因此请检查您传递给system(...) 的字符串是否包含任何&,如果是,请确保它们在shell 处理中被正确引用。

【讨论】:

  • 我已经编辑了这个问题,以明确我没有使用'&'来后台命令。不过好点。
  • @J.Chuchill:你确定,文本中不会有& 来替换吗?
  • 你的意思是在被传送到 sed 的文本中吗?即使有这怎么会是一个问题?我认为它不会被 shell 解释为后台进程的信号,它只是 sed 命令输入的一部分,不是吗?
  • 不,我的意思是作为命令行参数传递的 sed 脚本。如果该文本包含一些未正确转义的&符号,它将成为背景 sed。
  • 嗯,好的 - 我可以确认在 sed 脚本中肯定没有'&'。
【解决方案3】:

系统只会在其命令完成后返回,然后文件output 应该可以完整读取。但是……

...您的代码 sn-p 的多个实例并行运行会产生干扰,因为它们都使用相同的文件 output。如果您只想检查output 的内容而不需要文件本身,我会使用popen 而不是systempopen 允许您通过 FILE* 读取管道的输出。

在完整文件系统的情况下,您还可以看到一个空的output,而popen 版本在这种情况下没有问题。

要注意像完整文件系统这样的错误,请始终检查调用的返回码(system、popen、...)。如果有错误,联机帮助页会告诉您检查errno。数字errno 可以通过strerror 转换为人类可读的文本,并通过perror 输出。

【讨论】:

  • 感谢您的回答 - 我很欣赏您的观点,并已编辑我的问题以澄清。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-25
  • 2021-11-07
  • 1970-01-01
  • 2010-09-06
  • 1970-01-01
  • 1970-01-01
  • 2020-01-27
相关资源
最近更新 更多