我在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()时输出和读取的文件都是唯一的。
答案 0 :(得分:3)
在子进程终止之前,system()函数不会返回。
也许在失败时捕获“输出”的输出,看看它是什么?另外,检查system
的返回值是个好主意。一种情况是您正在运行的shell命令失败,并且您没有检查返回值。
答案 1 :(得分:3)
system(...)
调用标准shell来执行命令,shell本身应该在shell重新获得对终端的控制权之后返回。因此,如果有一个程序背景,系统将提前返回。
通过使用&
后缀命令来进行后台处理,因此请检查传递给system(...)
的字符串是否包含任何&
,如果是,请确保它们是从shell处理中正确引用的。< / p>
答案 2 :(得分:1)
系统只会在完成命令后返回,之后文件output
应该可以完整读取。但是......
...并行运行的代码段的多个实例会产生干扰,因为所有实例都使用相同的文件output
。如果您只是想检查output
的内容而不需要文件本身,我会使用popen
而不是system
。 popen
允许您通过FILE*
读取管道的输出。
如果是完整的文件系统,您还可以看到空output
,而popen
版本对此条件没有任何问题。
要注意完整文件系统之类的错误,请务必检查通话的返回代码(系统,popen,...)。如果出现错误,联机帮助页会告诉您检查errno
。 errno
号码可以strerror
转换为人类可读的文字,并由perror
输出。