UNIX 信號和陷阱
信號發送到一個程序來表示,一個重要的事件已經發生軟件中斷。事件可以從用戶請求訪問非法內存錯誤。一些信號,例如中斷信號,表明用戶提出的程序來完成的東西,而不是在通常的控制流。
以下是一些你可能會遇到的,要在程序中使用的更常見的信號:
信號名稱
信號數
描述
SIGHUP
1
Hang up detected on controlling terminal or death of controlling process
SIGINT
2
Issued if the user sends an interrupt signal (Ctrl + C).
SIGQUIT
3
Issued if the user sends a quit signal (Ctrl + D).
SIGFPE
8
Issued if an illegal mathematical operation is attempted
SIGKILL
9
If a process gets this signal it must quit immediately and will not perform any clean-up operations
SIGALRM
14
Alarm Clock signal (used for timers)
SIGTERM
15
Software termination signal (sent by kill by default).
信號一覽表:
有一個簡單的方法,列出了所有你的系統支持的信號。只要發出 kill -l 命令,它會顯示所有支持的信號:
$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
實際的信號列表之間的Solaris,HP-UX 和 Linux。
默認操作:
每個信號都有默認與它相關聯的動作。信號的默認操作是,當它接收信號的動作腳本或程序執行。
有些可能違反的操作是:
終止進程。
忽略信號。
核心轉儲。這將創建一個文件稱爲核心記憶形象的過程,當它收到的信號。
停止進程。
繼續停止的進程。
發送信號:
有幾種方法提供一個程序或腳本的信號。其中最常見的是執行腳本時用戶鍵入Control-C或INTERRUPT 鍵。
當你按下Ctrl+ C鍵發送一個SIGINT的腳本,並按照定義的默認動作腳本終止。
其他常見的傳送信號的方法是使用kill命令的語法如下:
$ kill -signal pid
signal 信號提供的電話號碼或姓名,pid是信號要發送到的進程ID。示例:
$ kill -1 1001
HUB或掛起信號發送到正在運行的程序的進程ID 1001。發送kill信號相同的過程使用以下命令:
$ kill -9 1001
這會殺死正在運行的進程的進程ID 1001。
捕獲信號:
當你按下Ctrl + C鍵或Break鍵在終端一個shell程序的執行過程中,正常程序將立即終止,並返回命令提示符。這可能並不總是可取的。例如,你可能最終留下了一堆臨時文件,將不會清理。
捕獲這些信號是很容易的,trap命令的語法如下:
$ trap commands signals
這裏的命令可以是任何有效的Unix命令,或什至一個用戶定義的函數,信號可以是任意數量的信號,你想來捕獲的列表。
在shell腳本中的陷阱有三種常見的用途:
清理臨時文件
忽略信號
清理臨時文件:
trap命令作爲一個例子,下面展示瞭如何可以刪除一些文件,然後退出,如果有人試圖從終端中止程序:
$ trap "rm -f $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2
執行shell程序,這個陷阱的角度,這兩個文件work1$$ 和 dataout$$ 將被自動刪除,如果程序接收信號數爲2。
因此,用戶中斷執行,如果執行的程序後,這個陷阱你可以放心,這兩個文件將被清理。 exit 命令如下 rm 是必要的,因爲沒有它的執行將繼續在節目中的一點,它離開時收到信號。
1號信號產生掛斷:要麼有人故意掛斷線路或線路被意外斷開。
您可以修改前面的陷阱也刪除指定的文件,在這種情況下,兩個信號信號1號添加到列表:
$ trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2
現在,這些文件將被刪除,如果該行被掛了,或者按Ctrl+ C鍵被按下。
來捕獲指定的命令必須用引號括起來,如果它們包含一個以上的命令。另外請注意,在 shell 命令行掃描 trap 命令得到執行,並再次當一個所列出的的信號被接收的時間。
WORKDIR 值 $$ 所以在前面的例子中,將被取代 trap 命令執行的時間。如果你想這種替代發生在收到信號1或2的時間你可以把單引號內的命令:
$ trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2
忽略信號:
如果陷阱列出的命令是空的,指定的信號接收時,將被忽略。例如,下面的命令:
$ trap '' 2
指定的中斷信號是被忽略的。你可能要忽略某些信號時進行一些操作,不希望打斷。可以指定多個信號被忽略如下:
$ trap '' 1 2 3 15
注意,第一個參數必須被指定爲一個信號被忽略,而不是相當於寫入下面的內容,它具有獨立的含義也各有:
$ trap 2
如果你忽略了一個信號,所有的子shell也忽略該信號。不過,如果指定要採取的行動在收到的信號,所有的子shell仍然會在收到該信號的默認操作。
重設陷阱:
當你改變了默認在收到信號後應採取的動作,你可以改變它回來的陷阱,如果你只是省略第一個參數;
$ trap 1 2
復位應採取的動作收到信號1或2 返回默認。