Linux 程序退出码
source link: https://zzyongx.github.io/blogs/linux-program-exit-codes.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Linux 程序退出码
这通常不是问题。写程序时,正常退出 exit(EXIT_SUCCESS)
,其它情况 exit(EXIT_FAILURE)
。而检查程序退出码时,判断 $?
是否等于0即可。但当我们想通过不同的退出码,表示不同的错误原因时,就有必要了解退出码的一些约定,例如 curl
命令,退出码含义非常丰富。
在 man 3 exit
中,exit的参数是个 int
,这很容易给人错觉,退出码可以是任意整数,然而并非如此,退出码的范围是 0-255
,exit函数会把 退出码 & 0xff
。
这里会再次给人以错觉,只要0-255的数字都可以,事实的确如此,然而却不是明智的选择,因为退出码多数都是要给bash使用的,而bash对错误码有自己的一套约定。
1 Bash对错误码的约定
empty_function() {}
缺少关键字或者命令或者权限问题
126
调用不可执行的命令
/dev/null
权限问题或者命令不可执行
127
命令没找到
illegal_command
命令不存在,或者 $PATH
配置问题
128
无效的exit参数
exit 3.14159
exit 只接受 0-255 范围的整数
128+n
收到信号n退出
kill -9 $PPID
$? 返回 137
以上参考 原文 ,综上, 1-2,126-164
是有特殊含义的退出码,用户在调用exit时,应该避免使用这些数字。
这些没有强制保证,仅从 $? = 137
无法确切判断是被kill了,还是 exit 137
退出了。
2 wait对错误码的处理
下面是一个例子,正常退出status是正数,值是退出码,收到信号退出是负数,值是信号值,128表示超时。
int status = 0; while (true) { if (waitpid(pid, &status, 0) == -1) { kill(-pid, SIGKILL); waitpid(pid, &status, 0); status = -128; } else { if (WIFEXITED(status)) { status = WEXITSTATUS(status); } else if (WIFSIGNALED(status)) { status = -WTERMSIG(status); } else if (WIFSTOPPED(status) || WIFCONTINUED(status)) { continue; } else { status = -128; } } break; }
wait得到的status值比 $?
丰富,借助宏能够获得详情,一些宏的定义如下:
#define __WTERMSIG(status) ((status) & 0x7f) #define __WIFEXITED(status) (__WTERMSIG(status) == 0) #define __WEXITSTATUS(status) (((status) & 0xff00) >> 8) #define __W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
如上可以看出真正的退出码在第二个8位,和信号有关的在低8位。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK