天天看點

自學Linux Shell15.1-處理信号

15.1-處理信号

Linux使用信号與系統上運作的程序進行通信。

可以使用這些信号控制Shell腳本的運作,隻需要讓shell腳本在接收到來自Linux系統的特定信号時執行指令即可。

1. 常用的Linux信号

編号 信号名稱 預設操作 解釋 POSIX
1 SIGHUP Terminate 挂起控制終端或程序
2 SIGINT Terminate 來自鍵盤的中斷
3 SIGQUIT Dump 從鍵盤退出
4 SIGILL Dump 非法指令
5 SIGTRAP Dump 跟蹤的斷點
6 SIGABRT Dump 異常結束
6 SIGIOT Dump 等價于SIGABRT
7 SIGBUS Dump 總線錯誤
8 SIGFPE Dump 浮點異常
9 SIGKILL Terminate 強迫程序終止
10 SIGUSR1 Terminate 對程序可用
11 SIGSEGV Dump 無效的記憶體引用
12 SIGUSR2 Terminate 對程序可用
13 SIGPIPE Terminate 向無讀者的管道寫
14 SIGALRM Terminate 實時定時器時鐘
15 SIGTERM Terminate 程序終止
16 SIGSTKFLT Terminate 協處理器棧錯誤
17 SIGCHLD Ignore 子程序停止、結束或在被跟蹤時獲得信号
18 SIGCONT Continue 如果已停止則恢複執行
19 SIGSTOP Stop 停止程序執行
20 SIGTSTP Stop 從tty發出停止程序
21 SIGTTIN Stop 背景程序請求輸入
22 SIGTTOU Stop 背景程序請求輸出
23 SIGURG Ignore 套接字上的緊急條件
24 SIGXCPU Dump 超過CPU時限
25 SIGXFSZ Dump 超過檔案大小的限制
26 SIGVTALRM Terminate 虛拟定時器時鐘
27 SIGPROF Terminate 概況定時器時鐘
28 SIGWINCH Ignore 視窗調整大小
29 SIGIO Terminate I/O現在可能發生
29 SIGPOLL Terminate 等價于SIGIO
30 SIGPWR Terminate 電源供給失敗
31 SIGSYS Dump 壞的系統調用
31 SIGUNUSED Dump 等價于SIGSYS
  • 預設情況下,bash shell會忽略它接收的任何SIGQUIT信号、SIGTERM信号(以防止互動的shell意外終止)。但是,bashshell處理它收到的任何SIGHUP、SIGINT信号。
  • 如果bash shell收到一個SIGHUP信号,它會退出。在退出之前,它将SIGHUP信号傳遞給shell啟動的任意程序(如shell腳本)。收到SIGINT信号,shell會立即中斷。Linux核心停止向shell提供CPU 上的處理時間。這種情況下,shell将SIGINT信号傳遞給由shell啟動的人任意程序以通知它們這種情況。
  • 預設的shell腳本行為将忽略這些信号,這樣會對腳本運作産生不良影響。為避免這種情況發生,對腳本進行程式設計以識别信号,并執行指令以便腳本為信号結果做好準備。

2. 生成信号

 Bashshell可以使用鍵盤上的組合鍵生成兩個基本的Linux信号。如果需要停止或暫停失控的程式,那麼這個功能會被用上。

2.1 中斷程序

使用Ctrl+C組合鍵可以生成SIGINT信号,并将其發送給目前正在shell中運作的任意程序。運作一個通常需要很長時間才能完成的指令并按Ctrl+C組合鍵,可以測試此操作。

Ctrl+C組合鍵不會在螢幕上生成任何輸出,它隻會停止目前在shell中運作的程序。sleep指令在指定的秒數之内暫停操作。

通常,指令提示符在計時器過期之前不會傳回。在計時器過期之前按Ctrl+C組合鍵,可以使sleep指令提前終止。

自學Linux Shell15.1-處理信号

2.2 暫停程序

Ctrl+Z組合鍵生成SIGSTP信号,可以停止任何在shell中運作的程序。停止程序與終止程序不同,停止程序後程式任然留在記憶體中,能夠從停止的地方繼續運作。

自學Linux Shell15.1-處理信号

方括号中的數字是shell配置設定的作業編号(jobnumber)。

shell以作業(job)形式引用shell中運作的每個程序,向每個作業配置設定唯一的作業編号。

它向第一個啟動的程序配置設定作業編号1,向第二程序配置設定作業編号2,以此類推。

如果shell會話中有一個停止的作業,在退出shell時bash将發出警告。使用ps指令檢視停止的作業:

自學Linux Shell15.1-處理信号

在S列(程序狀态),ps指令将已停止作業的狀态顯示為T

如果想在停止作業仍處于活動狀态時退出shell,隻需要再次鍵入exit指令。shell将退出,并終止亭子的作業。還有一種方法是知道停止作業的PID,使用kill指令發送SIGKILL信号來終止它。

自學Linux Shell15.1-處理信号

2.3 捕獲信号

除了可以使腳本忽略信号之外,還可以在信号出現時捕獲信号和執行其他指令。

trap指令可以指定能夠通過shell腳本監控和攔截的Linux信号。如果腳本收到trap指令中列出的信号,它将保護該信号不被shell處理,并在本地處理它。

trap指令格式:trap commands signals。在trap指令行中,隻需要列出希望shell執行的指令,以及希望捕獲的信号清單(以空格分隔)。指定信号可以通過它們的數值或Linux信号名實作。

自學Linux Shell15.1-處理信号

當每次檢測到SIGINT和SIGTERM信号時顯示一個簡單的文本消息。如果捕獲到這些信号,在使用者試圖使用bash shell鍵盤Ctrl+C指令停止程式時,腳本将不受影響。每次使用Ctrl+C組合鍵時,腳本執行trap指令中指定的echo語句,而不是忽略信号并允許shell停止腳本。

2.4 捕獲腳本退出   

除了在shell腳本中捕獲信号之外,可以在shell腳本退出時捕獲它們。這是一種在shell完成作業時執行指令的便捷方式。要捕獲shell腳本退出,隻需要向trap指令添加EXIT信号。   

自學Linux Shell15.1-處理信号

當腳本到達正常退出點時,就會觸發trap,shell将執行在trap指令行中指定的指令。

如果提前退出腳本,也能夠捕獲EXIT。使用Ctrl+C組合鍵發送SIGINT信号時,腳本退出,但是在腳本退出之前,shell将執行trap指令。

2.5 移除捕獲

要移除捕獲,使用破折号作為指令和想要恢複正常行為的信号清單。

自學Linux Shell15.1-處理信号

信号捕獲移除後,腳本将忽略信号。但是,如果在移除捕獲之前收到信号,腳本仍将根據trap指令處理該信号。

3. 背景模式下運作腳本

使用ps指令,可以檢視Linux系統上運作的程序。所有程序不在終端螢幕上運作。這就是所謂的背景運作程序。在背景模式中,程序運作時與終端會話STDIN、STDOUT和STDERR無關。

通過指令行界面以背景模式運作shell界面,隻需要在指令後加上一個&符号。将&符号放在指令之後時,它将bashshell與指令相分離,并以獨立的背景程序形式在系統上運作。

         顯示的一行類似:[1]  19555,方括号的數字是shell配置設定給背景的作業編号。後面的數字是LInux系統配置設定給程序的PID。所有Linux系統上運作的程序都必須有唯一的PID。

系統顯示這些條目之後,将出現一個新的指令行界面提示符。執行的指令将以後模式安全運作。

這是,可以在提示符處輸出新的指令,但是背景程序仍在運作,任然使用終端螢幕顯示STDOUT和STDERR消息。

背景程序結束時,在終端顯示消息格式:[1]+ Done       ./test  這表示作業編号和作業狀态(Done),以及用于啟動該作業的指令。

自學Linux Shell15.1-處理信号

可以通過指令行提示符同時啟動任何數量的背景作業。每次啟動一個新作業時,Linux系統将配置設定一個新作業編号和一個PID。使用ps指令可以檢視運作的所有腳本。

啟動的每個背景程序都出現在ps指令的運作程序輸出清單中。如果所有程序都在終端會中顯示輸出,那會變成一團糟。

4. 非控制台下運作腳本