我想获得一个Linux命令的输出string以及在C ++程序中的命令输出状态。 我在我的应用程序中执行Linux命令。
例如:命令:
rmdir abcd
命令输出string:
rmdir:无法删除`abcd':没有这样的文件或目录
命令状态:
1(表示命令失败)
我尝试使用提供输出状态的Linux函数system()
,函数popen()
给出了一个命令的输出string,但是这两个函数都不能同时给出Linux命令的输出string和输出状态。
输出字符串是标准输出或标准错误描述符(分别为1或2)。
你必须重定向这些流(看看dup
和dup2
函数)到一个地方,在那里你可以读取它们(例如 – 一个POSIX pipe
)。
在C我会做这样的事情:
int pd[2]; int retValue; char buffer[MAXBUF] = {0}; pipe(pd); dup2(pd[1],1); retValue = system("your command"); read(pd[0], buffer, MAXBUF);
现在,你的输出(缓冲区的一部分)和返回码在retValue中。
或者,你可以使用exec
(即execve
)函数,并获得wait
或waitpid
的返回值。
更新:这将只重定向标准输出。 要重定向标准错误,请使用dup2(pd[1],1)
。
最简单的解决方案是使用system
,并将标准错误和标准错误重定向到临时文件,稍后您可以删除它。
不幸的是,Linux上的C没有这么简单的方法。 下面是一个如何正确读取/写入子进程的stdout / stderr / stdin的例子。
而当你想要接收退出代码,你必须使用waitpid
(完整的例子在提供的页面底部提供):
endID = waitpid(childID, &status, WNOHANG|WUNTRACED);
现在,你只需要将这两者结合在一起:)
另外还有一本很好的免费书籍,叫做“高级程序设计” (ALP),其中包含有关此类问题的详细信息。
在上面的Piotr Zierhoffer答案的基础上,下面是一个函数,它也恢复stdout和stderr的原始状态。
// Execute command <cmd>, put its output (stdout and stderr) in <output>, // and return its status int exec_command(string& cmd, string& output) { // Save original stdout and stderr to enable restoring int org_stdout = dup(1); int org_stderr = dup(2); int pd[2]; pipe(pd); // Make the read-end of the pipe non blocking, so if the command being // executed has no output the read() call won't get stuck int flags = fcntl(pd[0], F_GETFL); flags |= O_NONBLOCK; if(fcntl(pd[0], F_SETFL, flags) == -1) { throw string("fcntl() failed"); } // Redirect stdout and stderr to the write-end of the pipe dup2(pd[1], 1); dup2(pd[1], 2); int status = system(cmd.c_str()); int buf_size = 1000; char buf[buf_size]; // Read from read-end of the pipe long num_bytes = read(pd[0], buf, buf_size); if(num_bytes > 0) { output.clear(); output.append(buf, num_bytes); } // Restore stdout and stderr and release the org* descriptors dup2(org_stdout, 1); dup2(org_stderr, 2); close(org_stdout); close(org_stderr); return status; }
你可以使用popen
系统调用,它将输出重定向到一个文件,并从文件中,你可以重定向输出到一个字符串。 喜欢 :
char buffer[MAXBUF] = {0}; FILE *fd = popen("openssl version -v", "r"); if (NULL == fd) { printf("Error in popen"); return; } fread(buffer, MAXBUF, 1, fd); printf("%s",buffer); pclose(fd);
欲了解更多信息,请阅读popen
man
页。