从C ++中已执行的Shell命令获取返回状态的安全方法是什么?

时间:2018-09-05 11:48:49

标签: c++ centos7 c++17

由于std::system(const char* command) doesn't guarantee that will return the correct return status from the shell中的函数cstdlib,那么如何使用c / c ++在shell中运行命令并保证可以给我正确的返回值? / p>

例如,我用以下命令运行了一个命令:

bool is_process_running(std::string p_name){
  std::string command_str= "ps aux | grep '" + p_name + "' | egrep -v '(grep|bash)'";

  int result(0);
  result= system(command_str.c_str());

  return result == 0;
}

例如,如果我直接运行ps aux | grep 'my_process' | egrep -v '(grep|bash)'到终端,然后在echo $?之后,我看到它返回0,因为my_process正在运行,并且还返回{{ 1}},当我使用非运行进程时。但是,上面的代码返回一个不同的值。当我在CentOs 6中进行测试时,该代码曾经可以工作,但是现在在CentOs 7中不再起作用。那么,我可以使用什么来运行shell命令并获得正确的结果?

我还找到了使用1命令的解决方案,但是我不能使用它,因为pidof不考虑传递给pidof的参数,因为我有很多此过程的实例,每个实例都带有不同的论点。

1 个答案:

答案 0 :(得分:0)

问题在于,不能保证the exit status of Bash是最后执行的命令的退出状态。如果您传递的命令中有错误,您将无法与egrep没有匹配任何内容真正区别开来。

您需要做的是同时获取退出状态解析输出(包括标准输出和标准错误)。这可以通过复制system函数的大部分操作来完成:首先为输出create a pipestderrstdout可以使用相同的管道),然后{ {3}}运行外壳程序,然后运行fork a new process

在父进程中,您execute the shell and the pipeline并获得其退出状态。如果为零,则说明一切正常,可以丢弃管道中的所有输出。如果它不为零,则必须读取管道的输出以查看发生了什么,除了egrep失败以外是否还有其他错误。