关于linux:Shell揭秘程序退出状态码

41次阅读

共计 2777 个字符,预计需要花费 7 分钟才能阅读完成。

程序退出状态码

前言

在本篇文章当中次要给大家介绍一个 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-LeHu…

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

正文完
 0