编写一个程序,该程序的方法是打开popen
命令到一个临时文件,读取输出并进行分析以供程序中的其他地方使用。如果命令成功,程序将按预期工作。但是,如果popen
尝试执行失败的命令,则该文件仍具有有效的指针,但是当程序尝试使用fgets
读取数据时,程序段将出错。
功能主体:
std::map<std::string,size_t> cols;
const char* command = command_string.c_str();
if (FILE *fp = popen(command,"r")) {
char buff[linesize];
std::vector<std::string> list;
std::cout << "here, popen succeeded\n";
std::cout << fp << '\n';
while (fgets(buff,linesize,fp)) {
std::cout << "here, fgets succeeded\n";
std::string data(buff);
list.push_back(data);
}
parse_cols(list);
pclose(fp);
}
else {
std::cout << "Failed to open bash shell when trying to run command\n";
std::exit(EXIT_FAILURE);
}
输出:
here, popen succeeded
0x1cc2430
sh: my_command: command not found
Segmentation fault (core dumped)
是否可以处理此错误?这是一个有用的错误,但我希望能够处理它,而不是仅仅依靠seg错误。我尝试查看FILE
结构,但是对于不同的C库版本似乎有所不同。
答案 0 :(得分:2)
Popen是野兽。仅在nullptr
或fork
失败时返回pipe
,但在您情况下则不会。
但是,您的程序不应出现段错误。当Shell返回失败时,您应该从有效(尽管为空)流中读取。比fgets()
返回NULL的原因是未读取任何字符而发生了文件结尾。
比起调用parse_calls
(我们看不到的函数),我有理由相信它不能处理空列表。当要查明不在popen
或fgets
中的实际问题时,崩溃堆栈可能会进一步提供帮助。