返回

在C++中如何获取system()调用输出?

windows

在 C++ 中获取 system() 调用输出

问题

在 C++ 中使用 system() 函数执行系统命令时,默认情况下输出信息会重定向到标准错误流 (stderr)。那么,如何获取这些输出信息呢?

解决方法

1. 流重定向

system() 函数的输出可以通过流重定向到标准输出流 (stdout) 来获取。具体步骤如下:

  • 创建管道。
  • 将 stdout 重定向到管道。
  • 执行命令。
  • 恢复 stdout。
  • 从管道中读取输出。
// 创建管道
std::string output;
int pipe[2];
if (pipe(pipe) == -1) {
    std::cerr << "Failed to create pipe" << std::endl;
    return -1;
}

// 重定向 stdout 到管道
dup2(pipe[1], STDOUT_FILENO);
close(pipe[1]);

// 执行命令
system(cmd.c_str());

// 恢复 stdout
dup2(STDOUT_FILENO, pipe[1]);
close(pipe[1]);

// 从管道中读取输出
char buffer[1024];
while (read(pipe[0], buffer, sizeof(buffer)) > 0) {
    output += buffer;
}
close(pipe[0]);

// 输出结果
std::cout << output << std::endl;

2. popen() 函数

popen() 函数可以创建管道并返回指向管道的文件指针。然后,可以使用 fread()getline() 函数从管道中读取输出。

// 打开管道
FILE* fp = popen(cmd.c_str(), "r");
if (fp == NULL) {
    std::cerr << "Failed to open pipe" << std::endl;
    return -1;
}

// 从管道中读取输出
std::string output;
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
    output += buffer;
}

// 关闭管道
pclose(fp);

// 输出结果
std::cout << output << std::endl;

注意

上述方法仅适用于命令输出到标准输出流 (stdout) 的情况。如果命令输出到标准错误流 (stderr),可以使用 dup2(pipe[1], STDERR_FILENO) 将 stderr 重定向到管道。

常见问题解答

1. 为什么使用流重定向而不是 popen() 函数?

流重定向可以更直接地控制管道,并且避免了创建新进程的开销。

2. 如何获取命令的退出状态?

使用 system() 函数时,可以使用 $? 获取命令的退出状态。

3. 如何处理命令输出过大的情况?

可以使用缓冲或分页技术来处理命令输出过大的情况。

4. 如何获取命令运行时产生的所有输出信息?

可以使用 tee 命令将输出信息重定向到管道和文件。

5. 是否可以将命令输出重定向到特定文件?

使用流重定向时,可以使用 freopen() 函数将输出重定向到特定文件。