Shell程序退出狀態(tài)碼的命令詳解
在本篇文章當(dāng)中主要給大家介紹了一些常見(jiàn)的程序退出的狀態(tài)碼!并且給出一下例子幫助大家仔細(xì)理解,并且使用C語(yǔ)言和python語(yǔ)言實(shí)現(xiàn)獲取子進(jìn)程退出時(shí)候的退出狀態(tài)碼。
程序退出狀態(tài)碼
前言
在本篇文章當(dāng)中主要給大家介紹一個(gè)shell的小知識(shí)——狀態(tài)碼。這是當(dāng)我們的程序退出的時(shí)候,子進(jìn)程會(huì)將自己程序的退出碼傳遞給父進(jìn)程,有時(shí)候我們可以利用這一操作做一些進(jìn)程退出之后的事情,比如當(dāng)程序執(zhí)行失敗或者被某個(gè)信號(hào)殺死我們就可以了解到,然后做出對(duì)應(yīng)的措施。
狀態(tài)碼簡(jiǎn)介

上圖是一個(gè)zsh的截圖,當(dāng)我們執(zhí)行命令asdsad之后,因?yàn)闆](méi)有這個(gè)命令,所以zsh(類似于bash的一種shell),輸出沒(méi)有找到這個(gè)命令,但是我們發(fā)現(xiàn)圖中箭頭??由綠色變成紅色,表示程序不是正常退出?,F(xiàn)在有一個(gè)問(wèn)題是,zsh是怎么知道程序不是正常退出的呢?其實(shí)就可以根據(jù)子進(jìn)程退出的狀態(tài)推斷。在文章的最后我們用C語(yǔ)言實(shí)現(xiàn)一下,看看如果在父進(jìn)程接收子進(jìn)程的退出的狀態(tài)。
我們?cè)诿钚挟?dāng)中可以通過(guò)命令 echo $? 查看上一個(gè)進(jìn)程退出時(shí)候的退出碼,這里的上一個(gè)進(jìn)程就是 ls 命令:

程序正常退出的時(shí)候退出碼等于0。
退出碼表
| 退出碼 | 含義 | 例子 | 解釋 |
|---|---|---|---|
| 1 | 一般的錯(cuò)誤 | 除以0 | 一般的除以0的錯(cuò)誤,執(zhí)行沒(méi)有權(quán)限的操作 |
| 2 | shell 內(nèi)部操作失敗 | 通常是shell操作時(shí)候的命令錯(cuò)誤,文章后面有一個(gè)例子演示 | |
| 126 | 執(zhí)行不能夠執(zhí)行的文件 | /dev/random | 權(quán)限問(wèn)題或者命令不能夠執(zhí)行 |
| 127 | 命令沒(méi)有找到 | 非法或者不存在的命令 | 執(zhí)行一個(gè)系統(tǒng)當(dāng)中不存在的命令,可以通過(guò)設(shè)置PATH環(huán)境變量 |
| 128+n | 錯(cuò)誤的信號(hào)值 | Kill -9 PID | 殺死進(jìn)程號(hào)為PID的進(jìn)程,進(jìn)程的退出碼等于 128 + 9 |
| 130 | ctrl+c 之后進(jìn)程的返回值 | 和上一條一樣ctrl+c的信號(hào)值等于2 | |
| 其他 | 退出碼s不在范圍之內(nèi) | exit(-1) | 如果退出碼n不在0-255之內(nèi),那么程序退出之后的退出碼為n&255,并且取低8位作為最終的結(jié)果 |
實(shí)例說(shuō)明
退出碼——1
除以0

執(zhí)行沒(méi)有權(quán)限的操作

上面直接進(jìn)入root用戶的目錄,因?yàn)闆](méi)有權(quán)限,查看進(jìn)程的退出碼等于1。
shell內(nèi)部操作失敗——退出碼2
a=1 if [ $a -eq 1 ] then echo hello world
比如對(duì)于上面的shell腳本是有語(yǔ)法錯(cuò)誤的正確的語(yǔ)法還需要在最后加上fi,現(xiàn)在我們執(zhí)行上面的腳本查看結(jié)果:

退出碼126
當(dāng)因?yàn)闄?quán)限問(wèn)題或者命令不可以執(zhí)行那么進(jìn)程的退出碼就是126:

命令沒(méi)有找到——退出碼127

信號(hào)值——128+n(信號(hào)對(duì)應(yīng)的數(shù)值)
我們可以使用kil -l 命令查看 linux 操作系統(tǒng)當(dāng)中信號(hào)以及對(duì)應(yīng)的數(shù)值:
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
當(dāng)我們?cè)诿钚惺褂胏trl+c中斷程序的執(zhí)行的時(shí)候,這個(gè)正在執(zhí)行的進(jìn)程就會(huì)接受到SIGINT信號(hào),根據(jù)上文這個(gè)信號(hào)對(duì)應(yīng)的數(shù)值為2,因此程序的退出碼等于130(128 + 2)。

下面是一個(gè)通過(guò)kill命令發(fā)送對(duì)應(yīng)的信號(hào)的例子:

可以看到的程序的退出碼是符號(hào)我們的預(yù)期的。
不在范圍內(nèi)不的退出碼
不在范圍內(nèi)(0-255)的退出碼,需要和 0xff 進(jìn)行 & 操作,得到的結(jié)果作為無(wú)符號(hào)數(shù)作為最終的程序的退出碼!

在上面的例子當(dāng)中退出碼256的二進(jìn)制表示 1_0000_0000 他和 255(二進(jìn)制表示為1111_1111)進(jìn)行與操作得到的結(jié)果為1_0000_000,低8位等于0000_0000,因此最終的退出碼等于0。

在上面的圖當(dāng)中-1的二進(jìn)制表示等于1111_1111 因此最后得到的退出碼等于1111_1111 = 255。
C/Python語(yǔ)言獲取進(jìn)程退出的狀態(tài)碼
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
int main() {
if(fork() == 0) {
_exit(1); // 子進(jìn)程執(zhí)行
} else {
// 父進(jìn)程執(zhí)行
int status;
wait(&status); // WEXITSTATUS 這個(gè)宏就是獲取子進(jìn)程退出時(shí)候的退出碼
printf("status = %d\n", WEXITSTATUS(status));
}
return 0;
}在上面的代碼當(dāng)中父進(jìn)程執(zhí)行的 wait 函數(shù)就是等待子進(jìn)程的狀態(tài)變化,當(dāng)子進(jìn)程退出的時(shí)候 wait 函數(shù)會(huì)返回,同時(shí)將子進(jìn)程一些狀態(tài)信息保存在 status 當(dāng)中,然后我們就可以子進(jìn)程傳遞給父進(jìn)程最后的信息啦。其中 WEXITSTATUS 這個(gè)宏就是獲取子進(jìn)程退出時(shí)候的退出碼!對(duì)應(yīng)的 python 實(shí)現(xiàn)如下圖所示:
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))總結(jié)
在本篇文章當(dāng)中主要給大家介紹了一些常見(jiàn)的程序退出的狀態(tài)碼!并且給出一下例子幫助大家仔細(xì)理解,并且使用C語(yǔ)言和python語(yǔ)言實(shí)現(xiàn)獲取子進(jìn)程退出時(shí)候的退出狀態(tài)碼。
以上就是本篇文章的所有內(nèi)容了,我是LeHung,我們下期再見(jiàn)?。?!更多精彩內(nèi)容合集可訪問(wèn)項(xiàng)目:https://github.com/Chang-LeHung/CSCore
到此這篇關(guān)于Shell程序退出狀態(tài)碼的文章就介紹到這了,更多相關(guān)Shell退出狀態(tài)碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Linux shell腳本編程if語(yǔ)句的使用方法(條件判斷)
這篇文章主要介紹了Linux shell腳本編程if語(yǔ)句的使用方法,大家參考使用吧2013-12-12
統(tǒng)計(jì) cpu 內(nèi)存 使用率的shell腳本代碼
統(tǒng)計(jì) cpu 內(nèi)存使用率的腳本,有需要的朋友可以參考下2013-02-02
linux C語(yǔ)言開(kāi)發(fā)管道通信實(shí)例詳解
這篇文章主要介紹了linux C語(yǔ)言開(kāi)發(fā)管道通信實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-01-01
通過(guò)Shell腳本批量創(chuàng)建服務(wù)器上的MySQL數(shù)據(jù)庫(kù)賬號(hào)
公司有數(shù)百臺(tái) MySQL 實(shí)例,如果手動(dòng)登入來(lái)創(chuàng)建賬號(hào)很麻煩,也不現(xiàn)實(shí)。所以,我們寫(xiě)了一個(gè)簡(jiǎn)單的shell腳本,用來(lái)創(chuàng)建批量服務(wù)器的mysql 賬號(hào)。這篇文章主要介紹了通過(guò)Shell腳本批量創(chuàng)建服務(wù)器上的MySQL數(shù)據(jù)庫(kù)賬號(hào)的相關(guān)知識(shí) ,需要的朋友可以參考下2019-07-07
shell腳本執(zhí)行命令自動(dòng)填充密碼(自動(dòng)輸入密碼)
這篇文章主要介紹了shell?執(zhí)行命令自動(dòng)填充密碼,文中結(jié)合實(shí)例代碼通過(guò)三種方式講解了Shell?腳本自動(dòng)輸入密碼的方法,需要的朋友可以參考下2023-02-02
很實(shí)用的Linux 系統(tǒng)運(yùn)維常用命令及常識(shí)(超實(shí)用)
作為L(zhǎng)inux運(yùn)維,需要了解Linux操作系統(tǒng)的基本使用和管理知識(shí),下面腳本之家小編給大家介紹下Linux運(yùn)維需要掌握的命令,想成為L(zhǎng)inux運(yùn)維的朋友可以來(lái)學(xué)習(xí)一下2016-10-10
Shell命令批量殺死進(jìn)程的方法實(shí)現(xiàn)
本文主要介紹了Shell命令批量殺死進(jìn)程的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06

