trap
捕捉信號和其他事件並執行命令。
概要
1trap [-lp] [[arg] signal_spec ...]
主要用途
- 用於指定在接收到信號後將要採取的動作。
- 腳本程序被中斷時執行清理工作。
選項
1-l 打印信號名稱以及信號名稱對應的數字。
2-p 顯示與每個信號關聯的trap命令。
參數
arg:接收到信號時執行的命令。
signal_spec:信號名稱或信號名稱對應的數字。
返回值
如果表達式執行結果爲成功時返回0,當參數 signal_spec
沒有指定有效值時返回1。
關於信號
信號是一種進程間通信機制,它給應用程序提供一種異步的軟件中斷,使應用程序有機會接受其他程序活終端發送的命令(即信號)。應用程序收到信號後,有三種處理方式:忽略,默認,或捕捉。進程收到一個信號後,會檢查對該信號的處理機制。如果是SIG_IGN,就忽略該信號;如果是SIG_DFT,則會採用系統默認的處理動作,通常是終止進程或忽略該信號;如果給該信號指定了一個處理函數(捕捉),則會中斷當前進程正在執行的任務,轉而去執行該信號的處理函數,返回後再繼續執行被中斷的任務。
在有些情況下,我們不希望自己的shell腳本在運行時刻被中斷,比如說我們寫得shell腳本設爲某一用戶的默認shell,使這一用戶進入系統後只能作某一項工作,如數據庫備份, 我們可不希望用戶使用 Ctrl+C 等方法進入到shell狀態做我們不希望做的事情。這便用到了信號處理。
以下是一些你可能會遇到的常見信號:
信號名稱 | 信號數 | 描述 |
---|---|---|
SIGHUP | 1 | 本信號在用戶終端連接(正常或非正常)結束時發出,通常是在終端的控制進程結束時,通知同一session內的各個作業,這時它們與控制終端不再關聯。登錄Linux時,系統會分配給登錄用戶一個終端(Session)。在這個終端運行的所有程序,包括前臺進程組和後臺進程組,一般都屬於這個Session。當用戶退出Linux登錄時,前臺進程組和後臺有對終端輸出的進程將會收到SIGHUP信號。這個信號的默認操作爲終止進程,因此前臺進程組和後臺有終端輸出的進程就會中止。對於與終端脫離關係的守護進程,這個信號用於通知它重新讀取配置文件。 |
SIGINT | 2 | 程序終止(interrupt)信號,在用戶鍵入 Ctrl+C 時發出。 |
SIGQUIT | 3 | 和SIGINT類似,但由QUIT字符(通常是Ctrl+\)來控制。進程在因收到SIGQUIT退出時會產生core文件,在這個意義上類似於一個程序錯誤信號。 |
SIGFPE | 8 | 在發生致命的算術運算錯誤時發出。不僅包括浮點運算錯誤,還包括溢出及除數爲0等其它所有的算術錯誤。 |
SIGKILL | 9 | 用來立即結束程序的運行。本信號不能被阻塞,處理和忽略。 |
SIGALRM | 14 | 時鐘定時信號,計算的是實際的時間或時鐘時間。alarm 函數使用該信號。 |
SIGTERM | 15 | 程序結束(terminate)信號, 與SIGKILL不同的是該信號可以被阻塞和處理. 通常用來要求程序自己正常退出;kill 命令缺省產生這個信號。 |
例子
當shell收到 HUP INT PIPE QUIT TERM
這幾個命令時,當前執行的程序會執行 exit 1
。
1[root@pc root]$ trap "exit 1" HUP INT PIPE QUIT TERM
1 清理臨時文件
下面展示瞭如果有人試圖從終端中止程序時,如何刪除文件然後退出:
1trap "rm -f $WORKDIR/work1 $WORKDIR/dataout; exit" 2
執行shell程序,如果程序接收信號爲2,那麼這兩個文件 (work1 和 dataout) 將被自動刪除。
添加信號1 SIGHUP
:
1$ trap "rm $WORKDIR/work1 $WORKDIR/dataout; exit" 1 2
2 忽略信號
如果陷阱列出的命令是空的,指定的信號接收時,將被忽略:
1$ trap '' 2
忽略多個信號:
1$ trap '' 1 2 3 15
3 重置陷阱
當你改變了收到信號後採取的動作,你可以省略第一個參數來重置到默認行爲。
1$ trap 1 2
注意
trap -l
等價於執行kill -l
。- 發送信號請查看
kill
命令。 - 該命令是bash內建命令,相關的幫助信息請查看
help
命令。 - 建議您閱讀以下參考資料來深入瞭解該命令:
- GNU 官方手冊: trap命令
- Linux Shell的信號trap功能你必須知道的細節
- 阮一峯: Bash 腳本如何創建臨時文件:mktemp 命令和 trap 命令教程
- 【Bash百寶箱】shell內建命令之trap
來源:https://github.com/jaywcjlove/linux-command
版權申明:
- 未標註來源的內容皆為原創,未經授權請勿轉載(因轉載後排版往往錯亂、內容不可控、無法持續更新等);
- 非營利為目的,演繹本博客任何內容,請以'原文出處'或者'參考鏈接'等方式給出本站相關網頁地址(方便讀者)。