我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何在bash中退出状态机制

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何在bash中退出状态机制

本篇文章为大家展示了如何在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 中#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 -10int 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 强转为 uint8Parent exit status: 102 # 10086 强转为 uint8

在 POSIX 标准中规定退出状态 0 代表该程序正常退出, 1 代表发生错误, 其他数字由程序自行规定, 因此在 glibc 的 stdlib.h 中仅定义了如下宏:

#define EXIT_FAILURE  1    #define EXIT_SUCCESS  0    

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

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

命令的退出状态

在 bash 中会记录所执行命令的退出状态, 可以通过 $? 获取最近执行的命令的退出状态. bash 自身的退出状态为执行的最后一条命令的退出状态, 也就等价于显式指定 exit $? . 如果没有执行任何命令就退出, 则 bash 的退出状态为 0 , 要注意在 bash 中用 0 表示 true , 用非零表示 false .

# 用 exit 显式指定退出状态> bash> exit 98exit> echo $?98# 什么也不执行则退出状态为 0> bashexit # Ctrl + D 退出> echo $?0# 默认为最后一条命令的退出状态> bash> ecasdecasd: command not foundexit # Ctrl + D 退出> echo $?127

在 bash 中对不同种类命令的退出状态作出如下规定:

内置命令: 由于内置命令执行时不需要启动额外的子进程, 因此需要用返回值模拟退出状态. 每个函数都定义了自己的退出状态, 例如: 内置命令 source 将脚本文件的最后一个命令的返回状态作为命令的返回状态. bash 中所有的内置命令都用退出状态 2 表示用法错误, 例如: 选项错误, 缺少参数.

> cd -+- # 错误的参数bash: cd: -+: invalid optioncd: usage: cd [-L|[-P [-e]] [-@]] [dir]> echo $?2

外部命令: 外部命令的退出状态就是使用 waitpid 得到的子进程的退出状态, 如果子进程在执行过程被编号为 N 的信号所终止, 则得到的退出状态就为 128+N .

Shell 函数: 定义 shell 函数时, 函数名与之前已定义的只读函数名相同则退出状态为 1 , 当发生语法错误则退出状态为 2 . 执行 shell 函数时, 函数中最后执行的一条命令的退出状态就是整个函数的退出状态.

# 二次定义只读函数报错> func () { echo; }> readonly -f func> func; echo $?0> func () { echo poi; }bash: func: readonly function> echo $?1# 定义函数发生语法错误> fune () {aa}bash: syntax error near unexpected token '{aa}'> echo $?2# 函数的退出状态是最后执行的命令的退出状态> funr () { echo; return 6; }> funr; echo $?  # echo 打印的空行6 # return 6 是函数中最后执行的命令

表达式: 使用 ((...)) 或 let 修饰的表达式的退出状态取决于表达式的值, 如果表达式的值为 0 则退出状态为 1 ; 如果表达式的值为非零, 则退出状态为 0 .

> let 0+0; echo $?1 # 表达式值为零> ((7-5)); echo $?0 # 表达式值非零

命令列表: 用 ; , & , && , || 连接命令被称为命令列表, 其中用 && 和 || 连接的命令使用左关联( left associativity )模式执行列表中的命令. 整个命令列表的退出状态为最后一条命令的退出状态. 此外, $( LISTS ) 以及流程控制结构如: for , while 等的返回状态也是结构中的命令列表的退出状态.

# 功能: 能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 $?0 # 无论是否能 ping 通, 命令列表的退出状态都等于最后一条命令的退出状态

左关联模式被广泛应用于各种语言的逻辑运算符优化中. 对于逻辑与运算符 && , 以 eq1 && eq2 为例, 只有当两边都为 True 才会返回 True , 因此当 eq1 为 False 时, eq2 不会执行; 对于逻辑或运算符 || , 以 eq1 || eq2 为例, 只要两边有一个 True 就会返回 True , 因此当 eq1 为 True 时, eq2 不会执行。

脚本: 使用 . 或 source 运行脚本文件等同于在当前 bash 中执行代码块, 脚本中最后执行的命令的退出状态就是脚本的退出状态. 使用 ./脚本名 或 bash 脚本名 的方式执行脚本文件等同于执行外部命令, 脚本的退出状态就是外部命令 bash 的退出状态. 如果脚本中最后执行的命令是 exit , 那么使用 . 或 source 执行该脚本文件在执行结束后会退出当前 bash .

后台作业与协作进程: 使用不带选项的 wait 命令可以获得最后一个执行完毕的后台作业的退出状态, 如果使用 wait -n <jobsec> 可以获得指定后台作业的退出状态, 如果作业不存在则退出状态为 127 . 使用 coproc 在 sub shell 中执行的命令的退出状态和后台作业一样可以被 wait 获取, coproc 自身的退出状态始终为 0 .

> { sleep 10; aad; } &[1] 558> wait -n 1[1]+ Exit 127        { sleep 10; aad; }> coproc { sleep 10; aad; }[1] 558> echo $?0 # 这是 coproc 的执行结果> jobs[1]+ Exit 127        coproc COPROC { sleep 10; aad; }

管道命令: 默认情况下, 管道的退出状态取决于管道中最后一条命令的退出状态. 如果设置了 set -o pipefail , 那么只有在管道中的全部命令的退出状态为 0 时, 整个管道的退出状态才为 0 , 否则就是最后一个非零的退出状态. 在管道前添加 ! 符号可以对整个管道的退出状态取反. bash 中的特殊变量 $PIPESTATUS 以数组的形式存储最近执行的前台管道的退出状态, 要注意的是单个命令也会被记录, 也就是说 ${PIPESTATUS[0]} 和 $? 是等价的.

# 管道的退出状态是最后一条命令的退出状态> ps | xxp 2>/dev/null | cat; echo $?0> set -o pipefail > ps | xxp 2>/dev/null | cat; echo $?127 # 设置了 pipefail 因此得到最后一个非零退出状态# 管道中每个命令的退出状态被按顺序记录在数组中> easd 2>/dev/null | ls /nou 2>/dev/null | more 2>/dev/null> echo ${PIPESTATUS[@]}127 2 0# 不带管道符号的单个命令也会被记录> ping asbasdasd 2>/dev/null; echo ${PIPESTATUS[0]}2> ping asbasdasd 2>/dev/null; echo $?2

上述内容就是如何在bash中退出状态机制,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何在bash中退出状态机制

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何在bash中退出状态机制

本篇文章为大家展示了如何在bash中退出状态机制,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。程序的退出状态当一个程序结束时会向父进程报告自己的退出状态( exit status ). 通过传递 i
2023-06-09

详解bash中的退出状态机制

程序的退出状态当一个程序结束时会向父进程报告自己的退出状态( exit status ). 通过传递 int 类型的变量给库函数 exit 或系统调用 _exit 可以设置当前程序的退出状态, 在 linux 中, 通过 WEXITSTAT
2022-06-04

电脑如何退出脱机状态

要将电脑从脱机状态恢复到在线状态,可以按照以下步骤操作:1. 首先,检查电脑是否已连接到互联网。确保该电脑已连接到可用的网络,并且网络连接正常。2. 如果网络连接正常,但电脑仍然显示脱机状态,可以尝试重新启动电脑。有时候重新启动可以解决网络
2023-09-06

如何使用Shell退出状态

如何使用Shell退出状态?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。退出状态和逻辑运算符的组合Shell if 语句的一个神奇之处是允许我们使用逻辑运算符将
2023-06-06

excel如何退出页眉编辑状态

退出页眉编辑状态的方法有两种:1. 使用快捷键:按下键盘上的Esc键,即可退出页眉编辑状态。2. 使用菜单栏:在Excel的菜单栏中,找到“视图”选项卡,点击“页眉和页脚”,然后再点击“关闭页眉和页脚”即可退出页眉编辑状态。
2023-09-11

iptables的状态机制如何分析

这篇文章给大家介绍iptables的状态机制如何分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1.6 状态机制状态机制是iptables中较为特殊的一部分,这也是iptables和比较老的ipchains的一个比较
2023-06-16

如何理解PHP中的无状态传输机制

PHP中的无状态传输机制在Web开发中,无状态传输机制是指服务器不会保存客户端的状态信息,每次请求都是独立的,服务器不会保持任何关于客户端状态的信息。PHP作为一种服务器端脚本语言,在处理HTTP请求时采用无状态传输机制,这对于维护服务器
如何理解PHP中的无状态传输机制
2024-03-06

mysql如何在cmd状态下导出数据库

要使用 cmd 导出 mysql 数据库,请按照以下步骤操作:连接到数据库。选择要导出的数据库。使用 mysqldump 命令导出数据库,添加 --opt 参数以优化输出。断开连接。如何在 CMD 状态下使用 MySQL 导出数据库要使用
mysql如何在cmd状态下导出数据库
2024-06-14

如何在Oracle中检查变量状态

在Oracle中,您可以使用以下语句来检查变量的状态:使用SHOW VARIABLE语句来查看当前会话中所有变量的值和状态。SHOW VARIABLE;使用DEFINE命令来定义一个变量,并使用PRINT命令来打印变量的值。DEFINE m
如何在Oracle中检查变量状态
2024-08-24

win10开机强制进入安全模式如何退出

本篇内容介绍了“win10开机强制进入安全模式如何退出”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、首先右键左下角开始菜单,打开“运行”
2023-07-02

如何在Python退出时强制运行一段代码

这篇文章将为大家详细讲解有关如何在Python退出时强制运行一段代码,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。设想这样一个场景,你要给一个项目开发测试程序,程序开始运行的时候,会创建初始
2023-06-03

织梦dedecms在模板页面中实现会员登录退出状态显示的方法

很多会员朋友在制作带会员中心的模板文件时候,当我们点击登录后,织梦默认是跳转到会员中心的,但在我们返回网站主页时,发现header没有显示会员登录信息,却在原始位置显示了登录信息,这是因为我们没有设置登录后的显示的位置及会员信息的调用。 因
2022-06-12

Shell $?如何获取函数返回值或者上一个命令的退出状态

这篇文章主要介绍“Shell $?如何获取函数返回值或者上一个命令的退出状态”,在日常操作中,相信很多人在Shell $?如何获取函数返回值或者上一个命令的退出状态问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答
2023-06-09

windows中打印机状态暂停如何处理

本篇内容主要讲解“windows中打印机状态暂停如何处理”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“windows中打印机状态暂停如何处理”吧!打印机状态暂停处理方法:方法一: 1、首先找到并
2023-07-02

静态导入机制如何在java项目中使用

这篇文章给大家介绍静态导入机制如何在java项目中使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。java中静态导入机制用法实例详解静态常量类在java开发中,我们会经常用到一些静态常量用于状态判断等操作。为了能够在
2023-05-31

如何解决电脑在空闲状态自动关机问题

这篇文章主要介绍了如何解决电脑在空闲状态自动关机问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.进入系统桌面,右键桌面的计算机图标,点击打开管理。在打开的计算机管理窗口
2023-06-28

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录