6

我想在 C++ 程序中获取 Linux 命令的输出字符串以及命令输出状态。我正在我的应用程序中执行 Linux 命令。

例如: 命令:

rmdir abcd

命令输出字符串:

rmdir: 删除 `abcd' 失败: 没有这样的文件或目录

命令状态:

1(表示命令失败)

我尝试使用system()给出输出状态的 Linux 函数和popen()给出命令输出字符串的函数,但是这两个函数都没有给出 Linux 命令的输出字符串和输出状态。

4

5 回答 5

7

输出字符串在标准输出或标准错误描述符中(分别为 1 或 2)。

您必须将这些流(查看dupdup2运行)重定向到可以阅读它们的地方(例如 - 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(ie ) 中的函数并使用orexecve获取返回值。waitwaitpid

更新:这将只重定向标准输出。要重定向标准错误,请使用dup2(pd[1],1).

于 2013-04-02T12:41:45.167 回答
3

最简单的解决方案是使用system, 并将标准输出和标准错误重定向到临时文件,您可以稍后将其删除。

于 2013-04-02T13:17:19.373 回答
2

不幸的是,在 Linux 上的 C 语言中没有简单的方法可以做到这一点。这是一个如何正确读取/写入子进程的 stdout/stderr/stdin 的示例。

当您想要接收退出代码时,您必须使用waitpid(完整示例在提供的页面底部提供):

endID = waitpid(childID, &status, WNOHANG|WUNTRACED);

现在你只需要将这两者结合在一起:)

还有一本很棒的免费书籍,名为A dvanced L inux P rogramming (ALP),其中包含有关此类问题的详细信息,请点击此处

于 2013-04-02T12:47:32.607 回答
1

基于上面 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;
}
于 2016-01-27T10:41:50.043 回答
0

您可以使用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);

欲了解更多信息,请阅读man页面popen

于 2014-05-26T09:16:49.927 回答