Linux shell編程之控制腳本之信號控制作業

控制腳本之信號控制作業

①信號基礎

②產生信號

③捕捉信號

④運行模式

後臺運行腳本

非控制檯下運行腳本

⑤作業控制

作業控制只查看作業

作業控制之重啓停止的作業

fg命令

bg命令

 


 

①信號基礎

>>>Linux系統上通過Linux信號可以實現對腳本的控制

>>>bash shell會忽略SIGQUIT3)和SIGTERM15)的信號,會處理SIGHUP1)和SIGINT2)的信號

Linux常見的系統信號

常見信號

描述

1

SIGHUP

掛起進程

2

SIGINT

終止進程

3

SIGQUIT

停止進程

9

SIGKILL

 無條件終止進程

15

SIGTERM

可能的話終止進程

17

SIGSTOP

無條件停止進程但不終止進程

18

SIGSTP

停止或者暫停進程,但不終止進程

19

SIGCONT

繼續停止的進程

說明:

        當bash shell收到SIGHUP信號時,bash shell會退出,但在退出之前,bash shell會將SIGHUP信號傳給shell啓動的所有進程(包括shell腳本)

        可以通過SIGINT信號去終端bash shell,當bash shell收到SIGINT信號時,會通知shell啓動的所有進程,SIGINT信號意味着Linux內核會停止將CPU處理時間分配給收到該信號的shell

 


 

②產生信號

>>>bash shell允許鍵盤上的按鍵組合產生基本的Linux信號

產生信號分類

按鍵組合

描述

Ctrl+C

發送SIGINT信號到當前正在運行的作業,讓作業終止

Ctrl+Z

發送SIGSTP信號,將一個正在前臺執行的任務進程放到後臺運行,並將任務進程掛起,此時狀態爲STOP

案例

[bei@localhost test]$ sleep 100
^Z
[1]+  Stopped                 sleep 100
[bei@localhost test]$ jobs
[1]+  Stopped                 sleep 100
#停止多個進程後
[beihuatao@localhost ~]$ jobs
[1]   Stopped                sleep 100
[2]   Stopped                 sleep 100
[3]-  Stopped                 sleep 100 : - 表示信號下一個處理的進程
[4]+  Stopped                 sleep 100 : + 表示信號處理的進程

說明:

bash shell會將shell中運行的每個進程稱爲作業(job)

bash shell會爲每個作業分配一個唯一的作業號,方括號中[ ]的數字表示的是shell分配的作業號

Stopped表示作業在後臺的狀態爲停止

可以使用ps命令查看已停止的作業,找到對應的PID,可以使用向作業發送SIGKILL信號的方式終止作業

案例

[bei@localhost test]$ ps -ef | grep "bei"
root      41490  41466  0 18:43 pts/1    00:00:00 su - bei
bei       41491  41490  0 18:43 pts/1    00:00:00 -bash
root      42614  42231  0 20:13 pts/2    00:00:00 su - bei
bei       42615  42614  0 20:13 pts/2    00:00:00 -bash
bei       42648  42615  0 20:14 pts/2    00:00:00 sleep 100
bei       42781  42615  0 20:36 pts/2    00:00:00 ps -ef
bei       42782  42615  0 20:36 pts/2    00:00:00 grep bei
[bei@localhost test]$ kill -9 42648
[bei@localhost test]$ ps -ef | grep "bei"
root      41490  41466  0 18:43 pts/1    00:00:00 su - bei
bei       41491  41490  0 18:43 pts/1    00:00:00 -bash
root      42614  42231  0 20:13 pts/2    00:00:00 su - bei
bei       42615  42614  0 20:13 pts/2    00:00:00 -bash
bei       42783  42615  0 20:36 pts/2    00:00:00 ps -ef
bei       42784  42615  0 20:36 pts/2    00:00:00 grep bei
[1]+  Killed                  sleep 100

說明:ps命令的第二列爲PID,輸入kill -9 PID即可終止進程

 


 

③捕捉信號

>>>默認情況下,shell腳本是不會去處理bash shell發送過來的信號

>>>可以使用trap命令指定shell腳本可以捕捉哪些信號

>>>當腳本收到了trap命令中列出的信號,trap命令會組織信號被shell處理,而在本地處理

     例:trap命令可以去監聽SIGSTP信號,當腳本收到SIGSTP信號時,trap命令就會捕捉這個信號,讓腳本不受影響

 

trap命令基本格式:

trap commands signals

>>>信號以空格分隔開,可以用數值,也可以用名稱

>>>commands表示當捕捉到信號,想要執行的shell命令

>>>命令用引號引起來,每次阻止到指定信號,都會執行命令

案例

[bei@localhost test]$ cat signal.sh
#!/bin/bash
trap "echo 'sorry,the signal[Ctrl+C] has been trapped.'" SIGINT
count=1
while [ $count -le 5 ]
do
        echo "sleep $count"
        sleep $count
        count=$[ $count + 1 ]
done
echo "end"
[bei@localhost test]$ bash signal.sh
sleep 1
sleep 2
sleep 3
^Csorry,the signal[Ctrl+C] has been trapped.
sleep 4
^Csorry,the signal[Ctrl+C] has been trapped.
sleep 5
end

說明:

此案例中,使用trap命令去捕捉SIGINT信號,若SIGINT信號被捕捉到,無法終止腳本,而會顯示一行文本

 


 

④運行模式

>>>大部分情況下,我們執行腳本是在命令行上直接運行,此時我們無法同時使用命令行進行其他操作,只有等待腳本執行結束

>>>當腳本運行時間過長時,如果需要使用命令行做其他事情,我們可以將腳本放入到後臺去運行

 

後臺運行腳本(與終端關聯)

>>>可以使用 bash scripts & 這種方式將scripts腳本放入到後臺運行

>>>腳本中的輸出(標準輸出或標準錯誤輸出)都會打印在屏幕上

>>>每個後臺進程都會綁定到該終端的繪畫的終端上(pts/0),當終端會話進程退出,會終止該終端後臺的進程

案例

[bei@localhost test]$ cat signal.sh
#!/bin/bash
count=1
while [ $count -le 5 ]
do
        echo "sleep $count"
        sleep $count
        count=$[ $count + 1 ]
done
echo "end"
[bei@localhost test]$ bash signal.sh &
[1] 43055
[bei@localhost test]$ sleep 1
sleep 2
sleep 3
sleep 4
[bei@localhost test]$
[bei@localhost test]$ ls -al
total 100
drwxrwxr-x. 2 bei bei 4096 Sep 25 21:10 .
drwxr-xr-x. 6 bei bei 4096 Sep 16 19:51 ..
-rw-rw-rw-. 1 bei bei  120 Sep 25 21:10 signal.sh
[bei@localhost test]$ sleep 5
pwd
/home/bei/linux/test
[bei@localhost test]$ end
[1]+  Done                    bash signal.sh

說明:

當腳本放入到後臺執行時會有一個輸出,如[1] 43055,
        其中[1]表示的是當前bash shell給這個作業分配的作業號,4305表式 分配給腳本的進程號PID

當腳本結束後,會有一個輸出,如 [1]+  Done                    bash signal.sh     表示腳本已結束

     

 

非控制檯下運行腳本(與終端不關聯)

>>>需求:即使終端會話進程退出,在後臺運行的腳本也不會退出,一直運行直到腳本自身運行完成

>>>可以使用nohup命令:nohup bash scripts &

>>>不會有標準輸出和標準錯誤輸出,而將輸出追加式重定向到nohup.out 文件中(輸出追加到此文件中,不刪除原來的內容)

>>>nohup bash scripts> myout.file 2>&1 &             #重定向到指定文件

案例

[bei@localhost test]$ cat signal.sh
#!/bin/bash
count=1
while [ $count -le 5 ]
do
        echo "sleep $count"
        sleep $count
        count=$[ $count + 1 ]
done
echo "end"
[bei@localhost test]$ nohup bash signal.sh  &
[1] 43155
[bei@localhost test]$ nohup: ignoring input and appending output to `nohup.out'


[bei@localhost test]$
[bei@localhost test]$ jobs
[1]+  Running                 nohup bash signal.sh &
[bei@localhost test]$
[1]+  Done                    nohup bash signal.sh
[bei@localhost test]$ ls -al ./nohup.out
-rw-------. 1 bei bei 88 Sep 25 21:26 ./nohup.out
[bei@localhost test]$ cat ./nohup.out
sleep 1
sleep 2
sleep 3
sleep 4
sleep 5
end

 


 

⑤作業控制

>>>作業控制:啓動、停止、無條件終止以及恢復作業等功能

 

作業控制只查看作業

>>>可以使用jobs命令查看後臺進程

[bei@localhost test]$ bash signal.sh
^Z
[1]+  Stopped                 bash signal.sh
[bei@localhost test]$ bash signal.sh &
[2] 43611
[bei@localhost test]$ jobs
[1]+  Stopped                 bash signal.sh
[2]-  Running                 bash signal.sh &

說明:

>>>對於作業[1]使用Ctrl+z掛起,在jobs中顯示Stopped表示作業已經暫時掛起

>>>對於作業[2],使用在執行腳本命令後面加上&符號,使它在後臺運行,在jobs中顯示Running表示作業正在運行中

>>>作業號的右邊有加號"+"和減號"-",帶加號的作業表示默認作業,表示使用作業控制命令時,未在命令行上指定作業號則默認操作的是帶加號的作業;帶減號的作業是帶加號的作業的備胎,比如kill掉作業[1],原來帶減號的作業[2]的減號就變成了加號

 

jobs命令相關選項說明

參數

描述

-l

列出進程的PID和對應的作業號

-n

只列出上次shell發出的通知後改變狀態的作業

-p

只列出作業的PID

-r

列出處於運行狀態的作業

-s

列出處於暫停狀態的作業

 

批量kill後臺的正在運行的所有進程

a= `jobs -p`                                #將所有進程的PID賦予給變量a

for i in $a;do kill $i;done      #如果想要kill後臺所有進程,包括stopped的進程,使用-9參數,無條件終止進程(慎用)

 

終止後臺指定作業號的作業:kill %number    (建議用作業號的方式kill,不用PID的方式)

[bei@localhost test]$ jobs
[1]-  Stopped                 bash signal.sh
[2]+  Stopped                 bash signal.sh
[3]   Running                 bash signal.sh &
[bei@localhost test]$ kill %3
[bei@localhost test]$ jobs
[1]-  Stopped                 bash signal.sh
[2]+  Stopped                 bash signal.sh
[3]   Terminated              bash signal.sh

注意:可以輸入命令 kill %

不指定作業號,則kill的作業是帶加號的作業

 

作業控制之重啓停止的作業

>>>fg命令:將後臺進程調至前臺運行

fg number            (如果不加number,默認操作的是有+的作業)

案例

[bei@localhost test]$ cat signal.sh
#!/bin/bash
count=1
while [ $count -le 5 ]
do
        echo "$count second sleep"
        sleep 1
        count=$[ $count + 1 ]
done
echo "End"
[bei@localhost test]$ bash signal.sh
1 second sleep
2 second sleep
3 second sleep
^Z
[1]+  Stopped                 bash signal.sh
[bei@localhost test]$ fg 1
bash signal.sh
4 second sleep
5 second sleep
End

 

>>>bg命令:將掛起的進程在後臺啓動爲運行狀態:

bg number    (如果不加number,默認操作的是有+的作業

案例

[bei@localhost test]$ bash signal.sh
1 second sleep
^Z
[1]+  Stopped                 bash signal.sh
[bei@localhost test]$ bg 1
[1]+ bash signal.sh &
[bei@localhost test]$ 2 second sleep
3 second sleep
jobs
[1]+  Running                 bash signal.sh &   #輸入jobs查看到作業正在後臺運行,輸出在屏幕上
[bei@localhost test]$ 4 second sleep
5 second sleep
End

[1]+  Done                    bash signal.sh

 

 


 

說明:

>>>以上內容是本人學習的總結

>>>如還有錯誤,請留言,指正

>>>亦可分享自己的想法,互相學習

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章