Linux命令 trap - 捕捉信號(hào)和其他事件并執(zhí)行命令

2022-03-22 09:35 更新

trap

捕捉信號(hào)和其他事件并執(zhí)行命令。

概要

trap [-lp] [[arg] signal_spec ...]

主要用途

  • 用于指定在接收到信號(hào)后將要采取的動(dòng)作。
  • 腳本程序被中斷時(shí)執(zhí)行清理工作。

選項(xiàng)

-l    打印信號(hào)名稱以及信號(hào)名稱對(duì)應(yīng)的數(shù)字。
-p    顯示與每個(gè)信號(hào)關(guān)聯(lián)的trap命令。

參數(shù)

arg:接收到信號(hào)時(shí)執(zhí)行的命令。

signal_spec:信號(hào)名稱或信號(hào)名稱對(duì)應(yīng)的數(shù)字。

返回值

如果表達(dá)式執(zhí)行結(jié)果為成功時(shí)返回0,當(dāng)參數(shù) signal_spec 沒(méi)有指定有效值時(shí)返回1。

關(guān)于信號(hào)

信號(hào)是一種進(jìn)程間通信機(jī)制,它給應(yīng)用程序提供一種異步的軟件中斷,使應(yīng)用程序有機(jī)會(huì)接受其他程序活終端發(fā)送的命令(即信號(hào))。應(yīng)用程序收到信號(hào)后,有三種處理方式:忽略,默認(rèn),或捕捉。進(jìn)程收到一個(gè)信號(hào)后,會(huì)檢查對(duì)該信號(hào)的處理機(jī)制。如果是SIG_IGN,就忽略該信號(hào);如果是SIG_DFT,則會(huì)采用系統(tǒng)默認(rèn)的處理動(dòng)作,通常是終止進(jìn)程或忽略該信號(hào);如果給該信號(hào)指定了一個(gè)處理函數(shù)(捕捉),則會(huì)中斷當(dāng)前進(jìn)程正在執(zhí)行的任務(wù),轉(zhuǎn)而去執(zhí)行該信號(hào)的處理函數(shù),返回后再繼續(xù)執(zhí)行被中斷的任務(wù)。

在有些情況下,我們不希望自己的shell腳本在運(yùn)行時(shí)刻被中斷,比如說(shuō)我們寫得shell腳本設(shè)為某一用戶的默認(rèn)shell,使這一用戶進(jìn)入系統(tǒng)后只能作某一項(xiàng)工作,如數(shù)據(jù)庫(kù)備份, 我們可不希望用戶使用 Ctrl+C 等方法進(jìn)入到shell狀態(tài)做我們不希望做的事情。這便用到了信號(hào)處理。

以下是一些你可能會(huì)遇到的常見(jiàn)信號(hào):

信號(hào)名稱信號(hào)數(shù)描述
SIGHUP1本信號(hào)在用戶終端連接(正常或非正常)結(jié)束時(shí)發(fā)出,通常是在終端的控制進(jìn)程結(jié)束時(shí),通知同一session內(nèi)的各個(gè)作業(yè),這時(shí)它們與控制終端不再關(guān)聯(lián)。登錄Linux時(shí),系統(tǒng)會(huì)分配給登錄用戶一個(gè)終端(Session)。在這個(gè)終端運(yùn)行的所有程序,包括前臺(tái)進(jìn)程組和后臺(tái)進(jìn)程組,一般都屬于這個(gè)Session。當(dāng)用戶退出Linux登錄時(shí),前臺(tái)進(jìn)程組和后臺(tái)有對(duì)終端輸出的進(jìn)程將會(huì)收到SIGHUP信號(hào)。這個(gè)信號(hào)的默認(rèn)操作為終止進(jìn)程,因此前臺(tái)進(jìn)程組和后臺(tái)有終端輸出的進(jìn)程就會(huì)中止。對(duì)于與終端脫離關(guān)系的守護(hù)進(jìn)程,這個(gè)信號(hào)用于通知它重新讀取配置文件。
SIGINT2程序終止(interrupt)信號(hào),在用戶鍵入 Ctrl+C 時(shí)發(fā)出。
SIGQUIT3和SIGINT類似,但由QUIT字符(通常是Ctrl /)來(lái)控制。進(jìn)程在因收到SIGQUIT退出時(shí)會(huì)產(chǎn)生core文件,在這個(gè)意義上類似于一個(gè)程序錯(cuò)誤信號(hào)。
SIGFPE8在發(fā)生致命的算術(shù)運(yùn)算錯(cuò)誤時(shí)發(fā)出。不僅包括浮點(diǎn)運(yùn)算錯(cuò)誤,還包括溢出及除數(shù)為0等其它所有的算術(shù)錯(cuò)誤。
SIGKILL9用來(lái)立即結(jié)束程序的運(yùn)行。本信號(hào)不能被阻塞,處理和忽略。
SIGALRM14時(shí)鐘定時(shí)信號(hào),計(jì)算的是實(shí)際的時(shí)間或時(shí)鐘時(shí)間。alarm 函數(shù)使用該信號(hào)。
SIGTERM15程序結(jié)束(terminate)信號(hào), 與SIGKILL不同的是該信號(hào)可以被阻塞和處理. 通常用來(lái)要求程序自己正常退出;kill 命令缺省產(chǎn)生這個(gè)信號(hào)。

例子

當(dāng)shell收到 HUP INT PIPE QUIT TERM 這幾個(gè)命令時(shí),當(dāng)前執(zhí)行的程序會(huì)執(zhí)行 exit 1。

[root@pc root]$ trap "exit 1" HUP INT PIPE QUIT TERM

1 清理臨時(shí)文件

下面展示了如果有人試圖從終端中止程序時(shí),如何刪除文件然后退出:

trap "rm -f $WORKDIR/work1 $WORKDIR/dataout; exit" 2

執(zhí)行shell程序,如果程序接收信號(hào)為2,那么這兩個(gè)文件 (work1 和 dataout) 將被自動(dòng)刪除。

添加信號(hào)1 SIGHUP:

$ trap "rm $WORKDIR/work1 $WORKDIR/dataout; exit" 1 2

2 忽略信號(hào)

如果陷阱列出的命令是空的,指定的信號(hào)接收時(shí),將被忽略:

$ trap '' 2

忽略多個(gè)信號(hào):

$ trap '' 1 2 3 15

3 重置陷阱

當(dāng)你改變了收到信號(hào)后采取的動(dòng)作,你可以省略第一個(gè)參數(shù)來(lái)重置到默認(rèn)行為。

$ trap 1 2

注意

  1. trap -l 等價(jià)于執(zhí)行 kill -l。
  2. 發(fā)送信號(hào)請(qǐng)查看 kill 命令。
  3. 該命令是bash內(nèi)建命令,相關(guān)的幫助信息請(qǐng)查看 help 命令。
  4. 建議您閱讀以下參考資料來(lái)深入了解該命令:


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)