程序退出状态码

前言

在本篇文章当中次要给大家介绍一个shell的小常识——状态码。这是当咱们的程序退出的时候,子过程会将本人程序的退出码传递给父过程,有时候咱们能够利用这一操作做一些过程退出之后的事件,比方当程序执行失败或者被某个信号杀死咱们就能够理解到,而后做出对应的措施。

状态码简介

上图是一个zsh的截图,当咱们执行命令asdsad之后,因为没有这个命令,所以zsh(相似于bash的一种shell),输入没有找到这个命令,然而咱们发现图中箭头➡️由绿色变成红色,示意程序不是失常退出。当初有一个问题是,zsh是怎么晓得程序不是失常退出的呢?其实就能够依据子过程退出的状态推断。在文章的最初咱们用C语言实现一下,看看如果在父过程接管子过程的退出的状态。

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

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

退出码表

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

实例阐明

退出码——1

除以0

执行没有权限的操作

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

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

a=1if [ $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) SIGUSR111) SIGSEGV    12) SIGUSR2    13) SIGPIPE    14) SIGALRM    15) SIGTERM16) SIGSTKFLT    17) SIGCHLD    18) SIGCONT    19) SIGSTOP    20) SIGTSTP21) SIGTTIN    22) SIGTTOU    23) SIGURG    24) SIGXCPU    25) SIGXFSZ26) SIGVTALRM    27) SIGPROF    28) SIGWINCH    29) SIGIO    30) SIGPWR31) SIGSYS    34) SIGRTMIN    35) SIGRTMIN+1    36) SIGRTMIN+2    37) SIGRTMIN+338) SIGRTMIN+4    39) SIGRTMIN+5    40) SIGRTMIN+6    41) SIGRTMIN+7    42) SIGRTMIN+843) SIGRTMIN+9    44) SIGRTMIN+10    45) SIGRTMIN+11    46) SIGRTMIN+12    47) SIGRTMIN+1348) SIGRTMIN+14    49) SIGRTMIN+15    50) SIGRTMAX-14    51) SIGRTMAX-13    52) SIGRTMAX-1253) SIGRTMAX-11    54) SIGRTMAX-10    55) SIGRTMAX-9    56) SIGRTMAX-8    57) SIGRTMAX-758) SIGRTMAX-6    59) SIGRTMAX-5    60) SIGRTMAX-4    61) SIGRTMAX-3    62) SIGRTMAX-263) 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 osimport sysif __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-LeHu...

关注公众号:一无是处的钻研僧,理解更多计算机(Java、Python、计算机系统根底、算法与数据结构)常识。