歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> SHELL編程 >> shell中trap捕獲信號

shell中trap捕獲信號

日期:2017/2/27 15:57:19   编辑:SHELL編程
信號是一種進程間通信機制,它給應用程序提供一種異步的軟件中斷,使應用程序有機會接受其他程序活終端發送的命令(即信號)。應用程序收到信號後,有三種處理方式:忽略默認,或捕捉。 進程收到一個信號後,會檢查對該信號的處理機制。如果是SIG_IGN,就忽略該信號;如果是SIG_DFT,則會采用系統默認的處理動作,通常是終止進 程或忽略該信號;如果給該信號指定了一個處理函數(捕捉),則會中斷當前進程正在執行的任務,轉而去執行該信號的處理函數,返回後再繼續執行被中斷的任 務。

在有些情況下,我們不希望自己的shell腳本在運行時刻被中斷,比如說我們寫得shell腳本設為某一用戶的默認shell,使這一用戶進入系統後只能 作某一項工作,如數據庫備份, 我們可不希望用戶使用Ctrl c之類便進入到shell狀態,做我們不希望做的事情。這便用到了信號處理。

以下是一些你可能會遇到的,要在程序中使用的更常見的信號:
信號名稱 信號數 描述 SIGHUP 1 本 信號在用戶終端連接(正常或非正常)結束時發出, 通常是在終端的控制進程結束時, 通知同一session內的各個作業, 這時它們與控制終端不再關聯。 登錄Linux時,系統會分配給登錄用戶一個終端(Session)。在這個終端運行的所有程序,包括前台進程組和後台進程組,一般都屬於這個 Session。當用戶退出Linux登錄時,前台進程組和後台有對終端輸出的進程將會收到SIGHUP信號。這個信號的默認操作為終止進程,因此前台進 程組和後台有終端輸出的進程就會中止。對於與終端脫離關系的守護進程,這個信號用於通知它重新讀取配置文件。 SIGINT 2 程序終止(interrupt)信號, 在用戶鍵入INTR字符(通常是Ctrl c)時發出。 SIGQUIT 3 和SIGINT類似, 但由QUIT字符(通常是Ctrl /)來控制. 進程在因收到SIGQUIT退出時會產生core文件, 在這個意義上類似於一個程序錯誤信號。 SIGFPE 8 在發生致命的算術運算錯誤時發出. 不僅包括浮點運算錯誤, 還包括溢出及除數為0等其它所有的算術的錯誤。 SIGKILL 9 用來立即結束程序的運行. 本信號不能被阻塞, 處理和忽略。 SIGALRM 14 時鐘定時信號, 計算的是實際的時間或時鐘時間. alarm函數使用該信號。 SIGTERM 15 程序結束(terminate)信號, 與SIGKILL不同的是該信號可以被阻塞和處理. 通常用來要求程序自己正常退出. shell命令kill缺省產生這個信號。
捕獲信號:
當你按下Ctrl + C鍵或Break鍵在終端一個shell程序的執行過程中,正常程序將立即終止,並返回命令提示符。這可能並不總是可取的。例如,你可能最終留下了一堆臨時文件,將不會清理。

捕獲這些信號是很容易的,trap命令的語法如下:
$ trap commands signals
這裡的命令可以是任何有效的Linux命令,或一個用戶定義的函數,信號可以是任意數量的信號,你想來捕獲的列表。

在shell腳本中的陷阱有三種常見的用途:
  1. 清理臨時文件
  2. 忽略信號
清理臨時文件:
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 返回默認。
原文:http://blog.linuxeye.com/391.html
Copyright © Linux教程網 All Rights Reserved