信號的類別
信號 | 值 | 描述 |
---|---|---|
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