亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Linux Shell > 正文

詳解bash中的退出狀態機制

2020-07-26 23:25:41
字體:
來源:轉載
供稿:網友

程序的退出狀態

當一個程序結束時會向父進程報告自己的退出狀態( exit status ). 通過傳遞 int 類型的變量給庫函數 exit 或系統調用 _exit 可以設置當前程序的退出狀態, 在 Linux 中, 通過 WEXITSTATUS 返回的退出狀態的值域為 [0, 255] 之間的整數 . 如果傳遞的值不在這個范圍內, 內核會自動幫你強轉為 u_int8_t . 通過 waitpid 庫函數可以得到子進程的退出狀態, 其值存儲在參數 wstatus 的低 8 位中.

// 定義在 wait.h 中# define WEXITSTATUS(status)  __WEXITSTATUS (status)// 定義在 waitstatus.h 中/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */#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    /* Failing exit status. */#define EXIT_SUCCESS  0    /* Successful exit status. */

程序本身一般會在文檔中事先約定每種退出狀態代表的退出原因( 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

參考資料

Exit status range
Bash man page

以上就是詳解bash中的退出狀態機制的詳細內容,更多關于bash 退出狀態 的資料請關注武林網其它相關文章!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品一区久久| 精品久久久久久久久久久久久久| 在线国产精品视频| 欧美精品成人在线| 欧美日韩在线免费观看| 亚洲自拍在线观看| 日韩av网站电影| 日韩免费在线视频| 国产精品成人一区二区| 91社区国产高清| 欧美视频专区一二在线观看| 色偷偷88888欧美精品久久久| 国产精品视频一区二区三区四| 亚洲最大中文字幕| xxx一区二区| 国产精品高潮呻吟久久av无限| 国产不卡av在线免费观看| 中文字幕久久亚洲| 亚洲自拍偷拍色片视频| 国产成人极品视频| 亚洲欧美国产制服动漫| 国产精品揄拍一区二区| 45www国产精品网站| 国产高清在线不卡| 一区国产精品视频| 91精品久久久久久久久久入口| 日韩av手机在线观看| 日韩在线视频线视频免费网站| 欧美裸体xxxx极品少妇软件| 欧美亚洲国产视频小说| 日韩精品在线免费| 成人精品一区二区三区电影黑人| 日韩精品免费观看| 国产精品视频男人的天堂| 亚洲一区二区三区xxx视频| 欧美激情影音先锋| 成人a视频在线观看| 亚洲国产婷婷香蕉久久久久久| 欧美有码在线观看视频| 久久亚洲国产精品成人av秋霞| www.日韩系列| 中文字幕国产亚洲| 国产成人免费av| 久久综合伊人77777尤物| 欧美另类极品videosbest最新版本| 91免费看国产| 一区二区三区日韩在线| 久久亚洲春色中文字幕| 亚洲视频在线免费观看| 亚洲国产一区自拍| 久久免费福利视频| 亚洲国产又黄又爽女人高潮的| 影音先锋欧美精品| 亚洲精品小视频| 超碰日本道色综合久久综合| 亚洲人成亚洲人成在线观看| 国产91免费观看| 欧美国产视频一区二区| 成人免费激情视频| 国产精品美乳一区二区免费| 亚洲国产小视频在线观看| 日韩精品中文字| 久久久精品一区二区三区| 日韩在线视频观看正片免费网站| 国产精品自产拍在线观看中文| 久久人人爽人人爽人人片亚洲| 国产亚洲欧洲黄色| 欧美精品久久久久久久免费观看| 日韩欧美一区二区三区久久| 欧美日韩一区二区在线播放| 欧美中文在线观看国产| 欧美在线性视频| 亚洲精品97久久| 欧美另类极品videosbestfree| 91免费国产视频| 日本在线观看天堂男亚洲| 亚洲自拍偷拍色片视频| 日韩高清中文字幕| 久久好看免费视频| 精品国产31久久久久久| 色播久久人人爽人人爽人人片视av| 亚洲娇小xxxx欧美娇小| 成人美女av在线直播| 日韩最新中文字幕电影免费看| 亚洲丁香婷深爱综合| 欧美性猛交xxxx富婆弯腰| 亚洲福利视频二区| 久久久噜噜噜久久| 国产精品专区h在线观看| 性色av一区二区咪爱| 欧美成人免费在线观看| 岛国av在线不卡| 亚洲理论在线a中文字幕| 久久久久久久久久婷婷| 欧美人与物videos| 欧美成人自拍视频| 精品国产网站地址| 国产亚洲一区精品| 成人做爰www免费看视频网站| 欧美精品久久久久久久免费观看| 国产精品久久久久久久av电影| 欧美国产精品人人做人人爱| 日韩中文字幕国产| 国产亚洲综合久久| 97国产一区二区精品久久呦| 黑人极品videos精品欧美裸| 欧美美女15p| 欧美一级片久久久久久久| 欧美极品欧美精品欧美视频| 日韩一区二区欧美| 日韩亚洲一区二区| 欧美性极品少妇精品网站| 国产精品99久久久久久久久久久久| 91久久久精品| 欧美亚洲免费电影| 日本精品在线视频| 国产一区视频在线播放| 久久天天躁狠狠躁老女人| 国产综合在线视频| 97精品一区二区三区| 91精品久久久久久久久不口人| 亚洲精品永久免费| 亚洲第一页中文字幕| 狠狠色香婷婷久久亚洲精品| 国产精品视频一区国模私拍| 日韩视频免费中文字幕| 亚洲成人av在线播放| 中文字幕av一区二区三区谷原希美| 久久久这里只有精品视频| 中文国产亚洲喷潮| 国产亚洲精品久久久久久777| 日韩av不卡电影| 最近2019中文字幕一页二页| 成人欧美一区二区三区在线湿哒哒| 久久成人国产精品| 久久视频中文字幕| 亚洲欧美日本伦理| 在线亚洲国产精品网| 欧美xxxx做受欧美.88| 国产精品久久久久秋霞鲁丝| 日韩网站免费观看| 日韩欧美在线字幕| 欧美在线精品免播放器视频| 日韩av电影国产| 91成人精品网站| 久久久在线视频| 日本不卡高字幕在线2019| 国产精品国产亚洲伊人久久| 国产成人jvid在线播放| 中文字幕亚洲欧美一区二区三区| 91禁国产网站| 午夜精品一区二区三区在线播放| 成人久久精品视频| 91精品在线播放| 超碰91人人草人人干| 日本免费一区二区三区视频观看| 91视频国产高清| 欧美在线性视频| 成人av在线网址| 精品美女久久久久久免费| 欧美激情一区二区三区成人| 91精品久久久久久综合乱菊| 色偷偷噜噜噜亚洲男人| 亚洲国产日韩欧美在线动漫|