Bash

為什麼將程序發送到後台設置$?到非零值?

  • June 9, 2020

我剛剛注意到將前台程序發送到後台Ctrl-Z並將$?變數設置為非零值。為什麼會這樣?

這種行為讓我很困擾,因為我希望有一個終端提示,當命令出錯時會改變顏色,我在這個答案之後做了這個。但是,這也意味著,如果我在 Vim 中工作,每次我將它發送到後台,Ctrl-Z提示都會改變顏色,就好像出了什麼問題一樣。

(假設bash

Ctrl-Z 不會將程序發送到後台(就像bg %JOB_NUMBER那樣),它會掛起它。為了做到這一點,一個 SIGSTP 信號被發送到程序(你可以自己做kill -SIGSTP PID)。SIGSTP 是信號 20。

您看到的返回值為148,或 128 + SIGSTP

因此,您應該更改該答案中的程式碼以檢查該條件,它始終為 148。

$?您看到的問題是由於使用了無法區分程序死亡原因並因此失去資訊的古董引起的。

$?包含exit()程式碼的低 8 位,127如果無法找到程序,如果可以找到126文件但無法執行或base+signal number如果程序被信號終止。base是一個取決於外殼的數字,通常為 128、256 或 512。

如果$?持有一個值為 126、127 或在 129..192 範圍內的數字,則無法判斷這是來自exit()孩子的程式碼,是由信號引起的還是由exec()錯誤引起的。

另請注意,其中的數字$?部分取決於作業系統,因為只有少數信號已授予標準化數字。SIGTSTP在具有未指定數字的信號中,仍然有一種方法可以在假設數字$?來自信號死亡的情況下獲取信號名稱。

檢查這個例子:

$ sleep 100^Z
$ echo $?
152
$ kill -l 152
TSTP

kill -l無論在目前作業系統上為命名信號使用的值和信號編號如何,都$?可以在任何POSIXshell上使用 from的值。base

如果您使用的是使用者友好的 shell(例如bosh),則有多個$?. 看這個例子:

$ sleep 100^Z
$ echo ${.sh.codename} ${.sh.termsig} ${.sh.status} $/ $?
KILLED TSTP 24 TSTP 152
$ (exit 1234567890)
$ echo ${.sh.codename} ${.sh.termsig} ${.sh.status} $/ $?
EXITED UNKNOWN 1234567890 1234567890 210

${.sh.codename}是名單中孩子死亡原因的名字EXITED KILLED DUMPED TRAPPED STOPPED CONTINUED NOEXEC NOTFOUND

${.sh.termsig}是與狀態碼相關的信號名稱

${.sh.status}是數字狀態碼。

上面的三個變數是bosh具體的。

$/是目前POSIX關於$?後繼程序的提議,其中包含程序正常退出時的數字和信號的文本或NOEXECNOTFOUND

exit()我的範例是使用僅適用於POSIX兼容作業系統的 32 位程式碼。該值210是表達式的結果1234567890 & 0xFF

引用自:https://unix.stackexchange.com/questions/591666