[英]does a C++ piped system call always end with EOF?
在此处使用SO帖子: 如何读取C ++中system()调用的结果?
我能够编写一个运行任意系统命令并以字符串形式返回任何输出的函数:
string pipeAndGetResults(string cmd)
{
const char* ccmd = cmd.c_str();
FILE* stream = popen( ccmd, "r" );
std::ostringstream output;
while( !feof( stream ) && !ferror( stream ))
{
char buf[128];
int bytesRead = fread( buf, 1, 128, stream );
output.write( buf, bytesRead );
}
string result = output.str();
boost::trim(result);
return result;
}
我一直将其用于“立即”产生值的系统命令。 我的问题是,如果cmd需要花费一些时间(例如一分钟)然后写入结果,此函数是否也将起作用。 我在用Python的pexpect
做类似的事情时遇到了问题; 如果cmd花了一段时间,它在等待结果时超时,并且我无法限制cmd的运行时间。 我相信这个问题可以简化为cmd在运行多长时间后是否总是写eof
?
feof()在输入流中未检测到EOF字符。 它指示是否尝试读取文件末尾之后的内容。 另外,根据我的经验,我会说大多数命令在它们的输出末尾不会写EOF字符。 fread()调用将一直阻塞,直到有要读取的数据为止,除非被中断,因此命令运行多长时间都没有关系。 根据所使用的操作系统,在出现信号的情况下,您可能可以告诉系统恢复中断的系统调用。 我也同意Bastile。 您应该使用更大的缓冲区以提高I / O效率。
除非该功能被中断,否则它将按预期运行。 顺便说一句,您的buf
很小(只有128个字节)。 我建议4或8 KB(请参阅带有PIPE_BUF
getconf(1) ):
while( !feof( stream ) && !ferror( stream ))
{
char buf[4096];
memset (buf, 0, sizeof(buf)); //probably useless
int bytesRead = fread(buf, 1, sizeof(buf), stream);
if (bytesRead < 0)
break;
output.write(buf,bytesRead);
}
另请阅读Advanced Linux Programming ...如果您想从同一进程进行读写,则可能需要在创建pipe(2) -s ....等之后与poll(2)进行多路复用。 。
用memset
将buf
归零可能不是真正需要的。 但是,如果上述程序存在错误,它将使其更具可重复性。 这就是为什么我喜欢清零内存的原因。 并且在这里将内存清零比读取内存要快得多。
参见fread(3)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.