c++ - 从c ++中执行的shell命令获取返回状态的安全方法是什么
问题描述
由于函数std::system(const char* command)
fromcstdlib
不保证会从 shell 返回正确的返回状态,那么我如何使用 c/c++ 在 shell 中运行命令并保证会给我正确的返回值?
例如,就我而言,我运行了一个命令:
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 命令并获得正确的结果?
我还找到了一个使用pidof
命令的解决方案,但我不能使用它,因为 pidof 不考虑传递给my_process
我需要的参数,因为我有很多这个进程的实例,每个实例都有不同的参数。
解决方案
问题是Bash 的退出状态不能保证是最后执行命令的退出状态。如果您传递的命令中有错误,您无法真正将其与egrep
未能匹配任何内容区分开来。
您需要做的是获取退出状态和解析输出(标准输出和标准错误)。这可以通过复制函数的大部分system
功能来完成:首先为输出创建一个管道(两者stderr
都stdout
可以使用相同的管道),然后派生一个新进程来运行 shell,然后执行 shell 和管道。
在父进程中,您等待子进程退出,并获取其退出状态。如果它为零,那么您就知道一切正常,您可以丢弃管道的所有输出。如果它不为零,则必须从管道读取输出以查看发生了什么,如果除了egrep
失败之外还有其他错误。
推荐阅读
- amazon - 如何在 Amazon Alexa 的自定义端点中获取用户输入
- wpf - ListBoxItem 样式中的某些事件未触发
- php - Laravel 服务端图表生成
- facebook - Facebook 错误 2FA
- c# - 如何在json单引号中写入c#字符串
- c++ - 这个对象初始化发生了什么?
- mysql - 我应该如何通过nodejs将大量数据导入mysql?
- google-chrome-extension - 允许控制允许 chrome 离线安装的源插件
- node.js - Angular/NodeJS Getstream.io 构建关注/取消关注按钮
- go - 延长长度,保持价值