在管道命令完成之前,system()是否可以返回

时间:2011-06-17 09:36:32

标签: c++ linux system libc

我在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;

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

我的问题是,当传入的整个命令完成或管道“|”存在时,system()是否应该返回管道完成后,mean system()可以在命令的一部分之前返回吗?

我明确没有使用'&'将命令的任何部分背景到system()。

为了进一步说明我在实践中运行代码片段并行多次,但输出文件是以线程ID命名的唯一文件名,每次调用system()时增加一个静态整数。我相信每次调用system()时输出和读取的文件都是唯一的。

3 个答案:

答案 0 :(得分:3)

根据documentation

  

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

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

答案 1 :(得分:3)

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

通过使用&后缀命令来进行后台处理,因此请检查传递给system(...)的字符串是否包含任何&,如果是,请确保它们是从shell处理中正确引用的。< / p>

答案 2 :(得分:1)

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

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

如果是完整的文件系统,您还可以看到空output,而popen版本对此条件没有任何问题。

要注意完整文件系统之类的错误,请务必检查通话的返回代码(系统,popen,...)。如果出现错误,联机帮助页会告诉您检查errnoerrno号码可以strerror转换为人类可读的文字,并由perror输出。