溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

在腳本中如何使用Bash信號(hào)捕獲

發(fā)布時(shí)間:2021-10-23 14:39:28 來源:億速云 閱讀:147 作者:小新 欄目:系統(tǒng)運(yùn)維

這篇文章將為大家詳細(xì)講解有關(guān)在腳本中如何使用Bash信號(hào)捕獲,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

Shell 腳本的啟動(dòng)并不難被檢測到,但 Shell 腳本的終止檢測卻并不容易,因?yàn)槲覀儫o法確定腳本會(huì)按照預(yù)期地正常結(jié)束,還是由于意外的錯(cuò)誤導(dǎo)致失敗。當(dāng)腳本執(zhí)行失敗時(shí),將正在處理的內(nèi)容記錄下來是非常有用的做法,但有時(shí)候這樣做起來并不方便。而 Bash 中 trap 命令的存在正是為了解決這個(gè)問題,它可以捕獲到腳本的終止信號(hào),并以某種預(yù)設(shè)的方式作出應(yīng)對(duì)。

響應(yīng)失敗

如果出現(xiàn)了一個(gè)錯(cuò)誤,可能導(dǎo)致發(fā)生一連串錯(cuò)誤。下面示例腳本中,首先在 /tmp 中創(chuàng)建一個(gè)臨時(shí)目錄,這樣可以在臨時(shí)目錄中執(zhí)行解包、文件處理等操作,然后再以另一種壓縮格式進(jìn)行打包:

#!/usr/bin/env bashCWD=`pwd`TMP=${TMP:-/tmp/tmpdir} ## create tmp dirmkdir "${TMP}" ## extract files to tmptar xf "${1}" --directory "${TMP}" ## move to tmpdir and run commandspushd "${TMP}"for IMG in *.jpg; do  mogrify -verbose -flip -flop "${IMG}"donetar --create --file "${1%.*}".tar *.jpg ## move back to originpopd ## bundle with bzip2bzip2 --compress "${TMP}"/"${1%.*}".tar \      --stdout > "${1%.*}".tbz ## clean up/usr/bin/rm -r /tmp/tmpdir

一般情況下,這個(gè)腳本都可以按照預(yù)期執(zhí)行。但如果歸檔文件中的文件是 PNG 文件而不是期望的 JPEG  文件,腳本就會(huì)在中途失敗,這時(shí)候另一個(gè)問題就出現(xiàn)了:最后一步刪除臨時(shí)目錄的操作沒有被正常執(zhí)行。如果你手動(dòng)把臨時(shí)目錄刪掉,倒是不會(huì)造成什么影響,但是如果沒有手動(dòng)把臨時(shí)目錄刪掉,在下一次執(zhí)行這個(gè)腳本的時(shí)候,它必須處理一個(gè)現(xiàn)有的臨時(shí)目錄,里面充滿了不可預(yù)知的剩余文件。

其中一個(gè)解決方案是在腳本開頭增加一個(gè)預(yù)防性刪除邏輯用來處理這種情況。但這種做法顯得有些暴力,而我們更應(yīng)該從結(jié)構(gòu)上解決這個(gè)問題。使用 trap 是一個(gè)優(yōu)雅的方法。

使用 trap 捕獲信號(hào)

我們可以通過 trap 捕捉程序運(yùn)行時(shí)的信號(hào)。如果你使用過 kill 或者 killall 命令,那你就已經(jīng)使用過名為 SIGTERM 的信號(hào)了。除此以外,還可以執(zhí)行 trap -l 或 trap --list 命令列出其它更多的信號(hào):

$ trap --list 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

可以被 trap 識(shí)別的信號(hào)除了以上這些,還包括:

  • EXIT:進(jìn)程退出時(shí)發(fā)出的信號(hào)

  • ERR:進(jìn)程以非 0 狀態(tài)碼退出時(shí)發(fā)出的信號(hào)

  • DEBUG:表示調(diào)試模式的布爾值

如果要在 Bash 中實(shí)現(xiàn)信號(hào)捕獲,只需要在 trap 后加上需要執(zhí)行的命令,再加上需要捕獲的信號(hào)列表就可以了。

例如,下面的這行語句可以捕獲到在進(jìn)程運(yùn)行時(shí)用戶按下 Ctrl + C 組合鍵發(fā)出的 SIGINT 信號(hào):

trap "{ echo 'Terminated with Ctrl+C'; }" SIGINT

因此,上文中腳本的缺陷可以通過使用 trap 捕獲 SIGINT、SIGTERM、進(jìn)程錯(cuò)誤退出、進(jìn)程正常退出等信號(hào),并正確處理臨時(shí)目錄的方式來修復(fù):

#!/usr/bin/env bashCWD=`pwd`TMP=${TMP:-/tmp/tmpdir} trap \ "{ /usr/bin/rm -r "${TMP}" ; exit 255; }" \ SIGINT SIGTERM ERR EXIT ## create tmp dirmkdir "${TMP}"tar xf "${1}" --directory "${TMP}" ## move to tmp and run commandspushd "${TMP}"for IMG in *.jpg; do  mogrify -verbose -flip -flop "${IMG}"donetar --create --file "${1%.*}".tar *.jpg ## move back to originpopd ## zip tarbzip2 --compress $TMP/"${1%.*}".tar \      --stdout > "${1%.*}".tbz

對(duì)于更復(fù)雜的功能,還可以用 Bash 函數(shù)來簡化 trap 語句。

關(guān)于“在腳本中如何使用Bash信號(hào)捕獲”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI