详解详解bash中的退出状态机制中的退出状态机制
程序的退出状态程序的退出状态
当一个程序结束时会向父进程报告自己的退出状态( exit status ). 通过传递 int 类型的变量给库函数 exit 或系统调用 _exit 可以
设置当前程序的退出状态, 在 Linux 中, 通过 WEXITSTATUS 返回的退出状态的值域为 [0, 255] 之间的整数 . 如果传递的值不
在这个范围内, 内核会自动帮你强转为 u_int8_t . 通过 waitpid 库函数可以得到子进程的退出状态, 其值存储在参数 wstatus 的
低 8 位中.
// 定义在 wait.h 中
# define WEXITSTATUS(status) __WEXITSTATUS (status)
// 定义在 waitstatus.h 中
/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
下面这个例子展示了如何使用 waitpid 及相关宏函数获取子进程的退出状态:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#define PARENT_EXIT 10086
#define CHILD_EXIT -10
int main()
{
pid_t pid = fork();
if (pid > 0)
{
int wstatus;
// 父进程等待子进程执行完毕, 用 WUNTRACED 选项追踪已结束的子进程
pid_t child_pid = waitpid(pid, &wstatus, WUNTRACED);
if (WIFEXITED(wstatus))
printf("Child exit status: %d", WEXITSTATUS(wstatus));
else
perror("Bad wait status");
// 父进程退出
exit(PARENT_EXIT);
}
else if (pid == 0)
{
// 子进程立即退出, 因此需要父进程设置 WUNTRACED
exit(CHILD_EXIT);
}
else
{
// 处理 fork 时出现的错误
perror("fork");
exit(EXIT_FAILURE);
}
}
编译并运行上例可以得到被强转后的状态码, 我们使用 WIFEXITED 判断等待的子进程是否执行成功, 然后对执行成功子进程使
用 WEXITSTATUS 获取其退出状态. 对程序来说, 最终的退出状态就是主进程的退出状态.
> gcc ecitcode.c;./a.out;echo "Parent exit status: $?"
Child exit status: 246 # -10 强转为 uint8
Parent exit status: 102 # 10086 强转为 uint8
在 POSIX 标准中规定退出状态 0 代表该程序正常退出, 1 代表发生错误, 其他数字由程序自行规定, 因此在 glibc 的 stdlib.h 中
仅定义了如下宏: