简体   繁体   English

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

[英]What is the safe way of get the return status from an executed shell command in c++

Since the function std::system(const char* command) from cstdlib doesn't guarantee that will return the correct return status from the shell , then how can I run a command in shell using c/c++ and have a guarantee that will give me the right return value? 由于cstdlib 的函数std::system(const char* command) 不能保证将从shell返回正确的返回状态 ,那么我如何使用c / c ++在shell中运行命令并保证将给出我正确的回报价值?

In my case, for example, I ran a command with: 以我为例,我使用以下命令运行:

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;
}

If I run, for example, ps aux | grep 'my_process' | egrep -v '(grep|bash)' 例如,如果我运行ps aux | grep 'my_process' | egrep -v '(grep|bash)' ps aux | grep 'my_process' | egrep -v '(grep|bash)' ps aux | grep 'my_process' | egrep -v '(grep|bash)' directly into the terminal and after that echo $? ps aux | grep 'my_process' | egrep -v '(grep|bash)'直接进入终端,然后echo $? , I see it returning 0 because my_process is running and also returning 1 when I use a non running process. ,我看到它返回0因为my_process正在运行,而当我使用未运行的进程时也返回1 But, the code above returns a different value. 但是,上面的代码返回一个不同的值。 This code used to work when I tested in CentOs 6 but now in CentOs 7 doesn't work anymore. 当我在CentOs 6中进行测试时,该代码曾经可以工作,但是现在在CentOs 7中不再起作用。 So, what can I use to run the shell command and get the correct result? 那么,我可以使用什么来运行shell命令并获得正确的结果呢?

I also found a solution using pidof command but I can't use this because pidof doesn't consider the parameters passed to my_process which I need since I have many instances of this process each with different arguments. 我还找到了使用pidof命令的解决方案,但是我不能使用它,因为pidof不会考虑传递给my_process的参数,因为我有许多该过程的实例,每个实例都有不同的参数,因此我不需要。

The problem is that the exit status of Bash isn't guaranteed to be the exit status of the last executed command. 问题在于不能保证Bash的退出状态是最后执行的命令的退出状态。 If there's an error in the command you pass, you can't really distinguish it from egrep failing to match anything. 如果您传递的命令中存在错误,则无法将其与egrep无法匹配任何内容区分开来。

What you need to do is to do is to both get the exit status and parse the output (both to standard output and standard error). 您需要做的就是获取退出状态解析输出(包括标准输出和标准错误)。 This can be accomplished by copying much of what the system function does: First create a pipe for the output (both stderr and stdout could be using the same pipe), then fork a new process to run the shell, and then execute the shell and the pipeline . 这可以通过复制大部分system功能来完成:首先为输出创建管道stderrstdout可以使用同一管道),然后派生一个新进程来运行Shell,然后执行Shell和管道

In the parent process you wait for the child to exit , and get its exit status. 在父进程中,您等待子进程退出 ,并获取其退出状态。 If it's zero then you know everything worked fine, and you can discard all the output from the pipe. 如果为零,则说明一切正常,可以丢弃管道中的所有输出。 If it's non-zero you have to read the output from the pipe to see what happened, if there was some error except egrep failing. 如果它不为零,则必须读取管道的输出以查看发生了什么,除了egrep失败以外是否还有其他错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM