如何捕获在C++中运行的命令的exit_code和stderr

How to capture the exit_code and stderr of the command that is run in C++?

本文关键字:exit code stderr 命令 C++ 运行 何捕获      更新时间:2023-10-16

我正在编写一个c++程序,该程序执行并输出(实时(shell脚本、makefile或其他程序。然而,当出现错误或没有错误时,我希望我的程序以不同的方式返回。

#include "execxi.h"

using namespace std;

int execXI::run(string command)
{
    FILE *in;
    char buff[512];
    // is this the check for command execution exited with not 0?
    if(!(in = popen(command.c_str(), "r"))){
            // I want to return the exit code and error message too if any
        return 1;
    }
    // this part echoes the output of the command that's executed
    while(fgets(buff, sizeof(buff), in)!=NULL){
        cout << buff;
    }
    pclose(in);
    return 0;

}

这就是我目前所拥有的。

假设这个脚本运行make来构建一个程序,它给出了一个类似的错误

on_target_webkit_version out/Release/obj/gen/webkit_version.h
Traceback (most recent call last):
  File "../build/webkit_version.py", line 107, in <module>
    sys.exit(main())
  File "../build/webkit_version.py", line 103, in main
    return EmitVersionHeader(*sys.argv[1:])
  File "../build/webkit_version.py", line 86, in EmitVersionHeader
    webkit_revision = GetWebKitRevision(webkit_dir, version_file)
  File "../build/webkit_version.py", line 60, in GetWebKitRevision
    version_info = lastchange.FetchVersionInfo(
AttributeError: 'module' object has no attribute 'FetchVersionInfo'
make: *** [out/Release/obj/gen/webkit_version.h] Error 1
  • 我有可能知道这是错误退出的吗?

    • 由于这是一个错误,是否会以代码else than 0退出?

    • 最后一部分是在stderr中输出的吗?

考虑到make退出时的代码不是0,比如说1,它在stderr中输出,我最后不可能捕捉到这些退出代码和错误消息吗?

如何在输出程序结果后捕获退出代码和stderr,并在函数中返回exit code/stderr

如果您对错误代码感兴趣,这是一种更便携的获取方法,而不是除以256:

printf("Exit code: %in", WEXITSTATUS(pclose(fp)));

然而,popen是一种方法,因此您要么通过shell中常见的重定向样式创建进一步的解决方案,要么遵循以下未经测试的代码来正确执行:

#include <unistd.h>
#include <stdio.h>
/* since pipes are unidirectional, we need two pipes.
   one for data to flow from parent's stdout to child's
   stdin and the other for child's stdout to flow to
   parent's stdin */
#define NUM_PIPES          2
#define PARENT_WRITE_PIPE  0
#define PARENT_READ_PIPE   1
int pipes[NUM_PIPES][2];
/* always in a pipe[], pipe[0] is for read and 
   pipe[1] is for write */
#define READ_FD  0
#define WRITE_FD 1
#define PARENT_READ_FD  ( pipes[PARENT_READ_PIPE][READ_FD]   )
#define PARENT_WRITE_FD ( pipes[PARENT_WRITE_PIPE][WRITE_FD] )
#define CHILD_READ_FD   ( pipes[PARENT_WRITE_PIPE][READ_FD]  )
#define CHILD_WRITE_FD  ( pipes[PARENT_READ_PIPE][WRITE_FD]  )
void
main()
{
    int outfd[2];
    int infd[2];
    // pipes for parent to write and read
    pipe(pipes[PARENT_READ_PIPE]);
    pipe(pipes[PARENT_WRITE_PIPE]);
    if(!fork()) {
        char *argv[]={ "/usr/bin/bc", "-q", 0};
        dup2(CHILD_READ_FD, STDIN_FILENO);
        dup2(CHILD_WRITE_FD, STDOUT_FILENO);
        /* Close fds not required by child. Also, we don't
           want the exec'ed program to know these existed */
        close(CHILD_READ_FD);
        close(CHILD_WRITE_FD);
        close(PARENT_READ_FD);
        close(PARENT_WRITE_FD);
        execv(argv[0], argv);
    } else {
        char buffer[100];
        int count;
        /* close fds not required by parent */       
        close(CHILD_READ_FD);
        close(CHILD_WRITE_FD);
        // Write to child’s stdin
        write(PARENT_WRITE_FD, "2^32n", 5);
        // Read from child’s stdout
        count = read(PARENT_READ_FD, buffer, sizeof(buffer)-1);
        if (count >= 0) {
            buffer[count] = 0;
            printf("%s", buffer);
        } else {
            printf("IO Errorn");
        }
    }
}

代码来自这里:

http://jineshkj.wordpress.com/2006/12/22/how-to-capture-stdin-stdout-and-stderr-of-child-program/

子进程的返回值位于顶部168位。你有将pclose的返回值除以256,得到已搜索子进程的返回值。

来自http://bytes.com/topic/c/answers/131694-pclose-returning-termination-status-command

我的答案是pclose(in)/256是退出代码。

我仍然不知道如何以不同的方式捕获stderr或sdtout,但在找到答案之前,我会接受这一点。

感谢您对退出代码Logan的回复。

我认为获取stderr的一个往返路径是将其重定向到一个临时文件:

FILE* f = popen("cmd 2>/tmp/tmpfile.txt", "r");