shell腳本5---信號處理

信號的類別

信號 描述
1 SIGHUP 掛起進程
2 SIGINT 終止進程
3 SIGQUIT 停止進程
9 SIGKILL 無條件終止進程
15 SIGTERM 優雅的終止進程
17 SIGSTOP 無條件停止進程,但不是終止進程
18 SIGTSTP 停止或暫停進程,但不是終止進程
19 SIGCONT 繼續運行停止的進程

默認情況下,bash shell會忽略收到的任何SIGQUIT(3)和SIGTERM(15)信號(正因爲這樣交互式shell纔不會被意外終止)。但是bash shell會處理收到的SIGHUP(1)和SIGINT(2)信號。

如果bash shell收到SIGHUP信號,它會退出。但在退出之前,它會將信號傳給shell啓動的所有進程(比如shell腳本)。通過SIGINT信號,可以中斷shell,Linux內核停止將CPU的處理時間分配給shell,當這種情況發生時,shell會將SIGINT信號傳給shell啓動的所有進程。

產生信號
  • 終止進程:ctrl+c
  • 暫停進程:ctrl+z,停止的進程繼續保留在內存中,並能從停止的位置繼續運行

在無條件終止作業時,開始不會得到任何反應。但下次有shell提示符時,你會看到一個消息說明作業已經被終止了。

$ sleep 100
^Z
[1]+ stopped sleep 100
$
$ kill -9 10650
$
[1]+ Killed sleep 100
$

方括號中的數字時shell分配的作業號。每當shell產生一個提示符時,它就會顯示shell中已經改變狀態的作業的狀態。在你無條件終止一個作業後,下次強制shell生成一個提示符時,shell會產生一條消息,說明作業在運行時被無條件終止了。

捕捉信號

trap命令允許你來指定shell腳本要watch哪些linux信號並從shell中攔截。如果腳本收到了trap命令中列出的信號,它會阻止它被shell處理,而在本地處理。
trap命令的格式:

trap commands signals

signals多個信號用空格隔開。
以下例子用trap命令來捕捉SIGINT和SIGTERM信號

#!/bin/bash

trap "echo 'Sorry! I have trapped Ctrl-C'" SIGINT SIGTERM
count=1
while [ $count -le 10 ]
do 
    echo "Loop #$count"
    sleep 5
    count=$[ $count + 1 ]
done
echo this is the end of the program

當我們執行Ctrl+C時,shell腳本不會中斷。

捕捉腳本的退出

要捕捉shell腳本的退出,只要在trap命令後加上EXIT信號就行。

#!/bin/bash
trap "echo Goodbye" EXIT

count=1
while [ $count -le 5 ]
do 
     echo "Loop #$count
      sleep 3
      count=$[ $count + 1 ]
done

執行這個腳本,在腳本執行完成退出前,會輸出Goodbye。

移除捕捉
trap -- signals
jobs

參數列表

參數 描述
-l 列出進程的PID以及作業號
-n 只列出上次shell發出的通知後改變了狀態的作業
-p 只列出作業的PID
-r 只列出運行中的作業
-s 只列出已停止的作業

jobs輸出中會有加號和減號。帶加號的作業會被當作默認作業。在使用作業控制命令時,如果未在命令行指定任何作業號,該作業會被當作操作對象。帶減號的作業則會在默認作業完成後成爲下一個默認作業。任何時候只有一個帶加號和一個帶減號的作業。

重啓停止的作業

在bash作業控制中,可以將已停止的作業作爲前臺或者後臺進程重啓。前臺進程會接管當前的工作終端。

  • bg <作業號> 重新在後臺啓動該作業
  • fg <作業號> 重新在前臺啓動該作業
nice 和 renice

nice命令允許在執行一個命令是調整它的調度優先級。優先級是一個整數值。從-20(最高優先級)到20(最低優先級)。默認情況下,bash shell以優先級0啓動所有進程。

nice -n 10 ./test4 > /tmp/test4out &

renice可以改變已運行命令的優先級。

renice 10 -p <PID>

普通用戶只能調整屬於自己進程的優先級。並且只能降低優先級。
root可以調整任何進程的優先級到任意級別。

計劃任務

如何設置一個計劃任務在每月的最後一天執行?

00 12 * * * if [ `date +%d -d tomorrow` = 01 ];then <command>;fi
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章