linux中shell中trap捕獲訊號

來源:互聯網
上載者:User

訊號是一種處理序間通訊機制,它給應用程式提供一種非同步軟體中斷,使應用程式有機會接受其他程式活終端發送的命令(即訊號)。應用程式收到訊號後,有三種處理方式:忽略預設,或捕捉。進程收到一個訊號後,會檢查對該訊號的處理機制。如果是SIG_IGN,就忽略該訊號;如果是SIG_DFT,則會採用系統預設的處理動作,通常是終止進程或忽略該訊號;如果給該訊號指定了一個處理函數(捕捉),則會中斷當前進程正在執行的任務,轉而去執行該訊號的處理函數,返回後再繼續執行被中斷的任務。

在有些情況下,我們不希望自己的shell指令碼在運行時刻被中斷,比如說我們寫得shell指令碼設為某一使用者的預設shell,使這一使用者進入系統後只能作某一項工作,如Database Backup, 我們可不希望使用者使用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指令碼中的陷阱有三種常見的用途:

    清理臨時檔案
    忽略訊號

清理臨時檔案:
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 返回預設。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.