程序退出状态码

前言

在本篇文章当中主要给大家介绍一个shell的小知识——状态码。这是当我们的程序退出的时候,子进程会将自己程序的退出码传递给父进程,有时候我们可以利用这一操作做一些进程退出之后的事情,比如当程序执行失败或者被某个信号杀死我们就可以了解到,然后做出对应的措施。

状态码简介

上图是一个zsh的截图,当我们执行命令asdsad之后,因为没有这个命令,所以zsh(类似于bash的一种shell),输出没有找到这个命令,但是我们发现图中箭头️由绿色变成红色,表示程序不是正常退出。现在有一个问题是,zsh是怎么知道程序不是正常退出的呢?其实就可以根据子进程退出的状态推断。在文章的最后我们用C语言实现一下,看看如果在父进程接收子进程的退出的状态。

我们在命令行当中可以通过命令 echo $? 查看上一个进程退出时候的退出码,这里的上一个进程就是 ls 命令:

程序正常退出的时候退出码等于0。

退出码表

退出码 含义 例子 解释
1 一般的错误 除以0 一般的除以0的错误,执行没有权限的操作
2 shell 内部操作失败 通常是shell操作时候的命令错误,文章后面有一个例子演示
126 执行不能够执行的文件 /dev/random 权限问题或者命令不能够执行
127 命令没有找到 非法或者不存在的命令 执行一个系统当中不存在的命令,可以通过设置PATH环境变量
128+n 错误的信号值 Kill -9 PID 杀死进程号为PID的进程,进程的退出码等于 128 + 9
130 ctrl+c 之后进程的返回值 和上一条一样ctrl+c的信号值等于2
其他 退出码s不在范围之内 exit(-1) 如果退出码n不在0-255之内,那么程序退出之后的退出码为n&255,并且取低8位作为最终的结果

实例说明

退出码——1

除以0

执行没有权限的操作

上面直接进入root用户的目录,因为没有权限,查看进程的退出码等于1。

shell内部操作失败——退出码2

a=1
if [ $a -eq 1 ]
then
echo hello world

比如对于上面的shell脚本是有语法错误的正确的语法还需要在最后加上fi,现在我们执行上面的脚本查看结果:

退出码126

当因为权限问题或者命令不可以执行那么进程的退出码就是126:

命令没有找到——退出码127

信号值——128+n(信号对应的数值)

我们可以使用kil -l 命令查看 linux 操作系统当中信号以及对应的数值:

 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX

当我们在命令行使用ctrl+c中断程序的执行的时候,这个正在执行的进程就会接受到SIGINT信号,根据上文这个信号对应的数值为2,因此程序的退出码等于130(128 + 2)。

下面是一个通过kill命令发送对应的信号的例子:

可以看到的程序的退出码是符号我们的预期的。

不在范围内不的退出码

不在范围内(0-255)的退出码,需要和 0xff 进行 & 操作,得到的结果作为无符号数作为最终的程序的退出码!

在上面的例子当中退出码256的二进制表示 1_0000_0000 他和 255(二进制表示为1111_1111)进行与操作得到的结果为1_0000_000,低8位等于0000_0000,因此最终的退出码等于0。

在上面的图当中-1的二进制表示等于1111_1111 因此最后得到的退出码等于1111_1111 = 255。

C/Python语言获取进程退出的状态码

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h> int main() { if(fork() == 0) {
_exit(1); // 子进程执行
} else {
// 父进程执行
int status;
wait(&status); // WEXITSTATUS 这个宏就是获取子进程退出时候的退出码
printf("status = %d\n", WEXITSTATUS(status));
}
return 0;
}

在上面的代码当中父进程执行的 wait 函数就是等待子进程的状态变化,当子进程退出的时候 wait 函数会返回,同时将子进程一些状态信息保存在 status 当中,然后我们就可以子进程传递给父进程最后的信息啦。其中 WEXITSTATUS 这个宏就是获取子进程退出时候的退出码!对应的 python 实现如下图所示:

import os
import sys if __name__ == '__main__':
pid = os.fork()
if pid == 0:
sys.exit(-1)
else:
pid, status = os.wait()
print(os.WEXITSTATUS(status))

总结

在本篇文章当中主要给大家介绍了一些常见的程序退出的状态码!并且给出一下例子帮助大家仔细理解,并且使用C语言和python语言实现获取子进程退出时候的退出状态码。


以上就是本篇文章的所有内容了,我是LeHung,我们下期再见!!!更多精彩内容合集可访问项目:https://github.com/Chang-LeHung/CSCore

关注公众号:一无是处的研究僧,了解更多计算机(Java、Python、计算机系统基础、算法与数据结构)知识。

Shell揭秘——程序退出状态码的更多相关文章

  1. shell中的退出状态码

    shell中的退出状态码最大只有255,如果超过这个值,就会进行取余运算,即如果执行如下命令: exit exitCode 如果exitCode大于255,那么实际的状态码为exitCode % 25 ...

  2. Shell中退出状态码exit

    shell中运行的每个命令都使用退出状态码(exit status)来告诉shell它完成了处理.退出状态码是一个0~255之间的整数值,在命令结束时由命令传回shell. 1 .查看退出状态码 Li ...

  3. linux退出状态码及exit命令

    Linux提供了一个专门的变量$?来保存上个已执行命令的退出状态码.对于需要进行检查的命令,必须在其运行完毕后立刻查看或使用$?变量.它的值会变成由shell所执行的最后一条命令的退出状态码: [ro ...

  4. Perl处理和收走子进程(退出状态码和wait)

    本文关于处理子进程退出状态码的内容主体来自于<Pro Perl>的第21章. 子进程退出状态码 每个子进程在退出时,操作系统都会保留它们的退出状态码,并在内核维护的进程表中保留子进程项.对 ...

  5. Linux退出状态码

    命令成功结束 一般性未知错误 不适合的shell命令 命令不可执行 没找到命令 无效的退出参数 +x 与Linux信号x相关的严重错误 通过Ctrl+C终止的命令 正常范围之外的退出状态码

  6. linux 退出状态码

    状态码 描述 0 命令成功结束 1 一般性未知错误 2 不适合的shell 命令 123 命令不可执行 127 没找到命令 128 无效退出参数 128+x 与linux信号x相关的严重错误 130 ...

  7. shell批量监控网站状态码

    shell批量监控网站状态码脚本,使用curl很慢.等我学完其他方式,在来更新. #!/bin/bash #GuoYabin yuming=`/bin/cat yuming.txt` for i in ...

  8. shell常见的返回状态码

  9. Linux shell编程-退出的状态码

    linux 提供了一个专门的变量$?来保存上个已执行命令的状态码 linux 的错误状态退出状态码没有什么标准可遵循,但有一些参考 状态码 描述 0 命令成功结束 1 一般性未知错误 2 不适合的sh ...

随机推荐

  1. Apache DolphinScheduler 1.3.8 发布

    小伙伴们  Apache DolphinScheduler 1.3.8 发布 2021年9月7日,正式发布 在 1.3.8 版本中,我们在 Docker&k8s 这里做了许多优化,Docker ...

  2. CSP AFO后可以公开的情报

    10.08 早上和下午准备初赛,晚上考了套题,然后就摸文化课去了. \(250/250\) 手动模拟确实效果好 经验是把双刃剑,读题细致才是王道 T3是分治,一看到1e5的数据就习惯性往数据结构想,一 ...

  3. HTTPS 一定是安全的吗?

    大家好,我是小林. 上周有位读者在面字节时被问道这么一个问题:HTTPS 一定安全可靠吗? 这个问题的场景是这样的:客户端通过浏览器向服务端发起 HTTPS 请求时,被「假基站」转发到了一个「中间人服 ...

  4. Downie for Mac最强视频下载工具(支持B站优酷土豆腾讯等)

    我搜集到的一款简单拖放链接到Downie,它就会下载该网站上的视频.理论可以下载各种视频网站上的视频! 应用介绍 Downie 是一款Mac平台上的优秀视频下载软件,使用非常简单,只需将下载链接放置D ...

  5. 【Java】学习路径49-练习:使用两个不同的线程类实现买票系统

    练习:使用两个不同的线程类实现买票系统 请创建两个不同的线程类.一个测试类以及一个票的管理类. 其中票的管理类用于储存票的数量.两个线程类看作不同的买票方式. 步骤: 1.创建所需的类 App售票线程 ...

  6. 巧用 transition 实现短视频 APP 点赞动画

    在各种短视频界面上,我们经常会看到类似这样的点赞动画: 非常的有意思,有意思的交互会让用户更愿意进行互动. 那么,这么有趣的点赞动画,有没有可能使用纯 CSS 实现呢?那当然是必须的,本文,就将巧妙的 ...

  7. 第二十四篇:对于dom的理解

    好家伙, HTML            CSS              JS structure style        function 结构体    样式     功能 <>   ...

  8. [第二章 web进阶]XSS闯关-1

    定义:跨站脚本(Cross_Site Scripting,简称为XSS或跨站脚本或跨站脚本攻击)是一种针对网站应用程序的安全漏洞攻击技术,是代码注入的一种.它允许恶意用户将代码注入网页,其他用户浏览网 ...

  9. 手写tomcat——netty版

    点击查看代码 package com.grady.diytomcat; import com.grady.diytomcat.handler.DiyNettyTomcatHandler; import ...

  10. 【android 逆向】破解crackme0502

    1.首先将crackme0502 拖入模拟器.打开应用,随意输出字符串 2. 将APK 拖入AndroidKiller 反编译 3.先查看androidmanifest.xml <?xml ve ...