程序的退出状态

当一个程序结束时会向父进程报告自己的退出状态( 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\n", WEXITSTATUS(wstatus));
    else
      perror("Bad wait status\n");

    // 父进程退出
    exit(PARENT_EXIT);
  }
  else if (pid == 0)
  {
    // 子进程立即退出, 因此需要父进程设置 WUNTRACED
    exit(CHILD_EXIT);
  }
  else
  {
    // 处理 fork 时出现的错误
    perror("fork\n");
    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 中仅定义了如下宏:

#define EXIT_FAILURE  1    /* Failing exit status. */
#define EXIT_SUCCESS  0    /* Successful exit status. */

程序本身一般会在文档中事先约定每种退出状态代表的退出原因( termination ), 例如在 ls 的帮助文档中:

> ls --help
...其他内容...
Exit status: # 退出状态
 0 if OK, # 正常执行
 1 if minor problems # 次要问题, 例如: 无法访问子目录
 2 if serious trouble # 严重错误, 例如: 无法访问命令行参数
...其他内容...

命令的退出状态

在 bash 中会记录所执行命令的退出状态, 可以通过 $"htmlcode">

# 用 exit 显式指定退出状态
> bash
> exit 98
exit
> echo $"htmlcode">
> cd -+- # 错误的参数
bash: cd: -+: invalid option
cd: usage: cd [-L|[-P [-e]] [-@]] [dir]
> echo $"htmlcode">
# 二次定义只读函数报错
> func () { echo; }
> readonly -f func
> func; echo $"htmlcode">
> let 0+0; echo $"htmlcode">
# 功能: 能ping通baidu.com则输出 `baidu.com is up` , 否则输出 `baidu.com is down` 。
> ping -c1 baidu.com &> /dev/null && echo 'baidu.com is up' || echo 'baidu.com is down'
baidu.com is down
> echo $"htmlcode">
> { sleep 10; aad; } &
[1] 558
> wait -n 1
[1]+ Exit 127        { sleep 10; aad; }

> coproc { sleep 10; aad; }
[1] 558
> echo $"htmlcode">
# 管道的退出状态是最后一条命令的退出状态
> ps | xxp 2>/dev/null | cat; echo $"color: #ff0000">参考资料

Exit status range
Bash man page

以上就是详解bash中的退出状态机制的详细内容,更多关于bash 退出状态 的资料请关注其它相关文章!

标签:
bash,退出状态,bash,退出

免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
评论“详解bash中的退出状态机制”
暂无“详解bash中的退出状态机制”评论...

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。