Linux下如何捕获timeout工具的返回值并打印错误码?
正确捕获Linux timeout工具返回值的方法
我来帮你搞定这个问题——你用C++的system()调用timeout时返回值不符合预期,核心问题是**system()的返回值并不是直接的命令退出码**,而是一个包含进程终止状态的复合值,得用特定的宏来解析才行。
一、为什么你的代码返回值不符合预期?
system()函数的返回值来自waitpid()的状态信息,目标命令的实际退出码被存在这个值的高8位里。比如当timeout返回124时,system()返回的其实是124 << 8(也就是31744),直接打印res自然和你预期的124对不上。
二、正确解析timeout返回值的代码示例
你需要引入<sys/wait.h>头文件,用里面的宏来拆解system()的返回值,再结合timeout的返回规则判断具体情况:
#include <iostream> #include <string> #include <sys/wait.h> // 必须包含这个头文件来使用状态解析宏 #include <cstring> // 用于strerror() int main() { std::string syscommand = "timeout -s KILL 1s sleep 2"; // 用sleep 2模拟超时场景 int res = system(syscommand.c_str()); // 先判断system调用本身是否失败 if (res == -1) { std::cerr << "system调用执行失败:" << strerror(errno) << std::endl; return 1; } // 解析进程终止状态 if (WIFEXITED(res)) { int exit_code = WEXITSTATUS(res); std::cout << "命令正常退出,退出码:" << exit_code << std::endl; // 对照timeout的返回规则判断场景 switch(exit_code) { case 124: std::cout << "→ 超时:目标command执行超过指定时间" << std::endl; break; case 125: std::cout << "→ timeout自身执行失败" << std::endl; break; case 126: std::cout << "→ 找到目标command但无法执行" << std::endl; break; case 127: std::cout << "→ 未找到目标command" << std::endl; break; default: std::cout << "→ 目标command正常完成,退出码:" << exit_code << std::endl; break; } } else if (WIFSIGNALED(res)) { int sig_num = WTERMSIG(res); int exit_code = 128 + sig_num; std::cout << "进程被信号终止,信号编号:" << sig_num << "(对应退出码:" << exit_code << ")" << std::endl; if (sig_num == 9) { std::cout << "→ 目标command被KILL信号强制终止" << std::endl; } } return 0; }
三、关于打印错误码的说明
- timeout的自定义退出码:像124、125、137这些是
timeout工具自己定义的返回码,不属于系统标准错误码,所以用strerror()无法获取对应的描述,直接按照官方规则判断即可。 - 系统调用错误:如果
system()返回-1,说明调用本身失败(比如无法创建子进程),这时可以用strerror(errno)打印具体的系统错误信息。
内容的提问来源于stack exchange,提问作者user7163017
相关产品推荐
相关产品推荐

