国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

第12章 處理信號

2019-11-08 18:22:01
字體:
來源:轉載
供稿:網友

信號就像一個軟中斷,當有一些重要的事情發生時,它們就會被發送到程序中。

本章要學習的知識點:

(1)在系統中如何表達信號;

(2)如何查看系統中所有的信號名和對應的數字;

(3)shell編程中常用到哪些信號;

(4)如何發送特定的信號;

(5)如何處理收到的信號;

(6)如何忽略某些信號及如何恢復它們;

(7)如何在腳本退出時做某些特定的處理;

1.     如何表達信號

信號實際上就是一個進程發送給另一個進程的消息,實現進程互通。

 現在linux系統中有幾十種信號的類型,每一個信號都被分配了一個數字和一個名字。在使用時,既可以用數字,也可以用名字。在shell命令行中,可以通過trap-l或kill -l來查看系統中所有的信號。

 通過使用bash的內建命令kill可以發送任意指定的信號到某個進程。如果沒有指定參數,kill命令默認發送信號15SIGTERM,在接收這個信號后,進程會終止執行。

    kill命令的格式如下:

       Kill [ -s sigspec | -n signum | -sigspec ] [pid | jobspec ]…

 通過sigspec或signum指定要發送的信號,sigspec既可以是任意大小寫的信號名(有無SIG前綴都可以),也可以是給信號分配的數字,而signum只能是數字。kill命令會把指定的信號發送給進程號為pid的進程,或者發送給作業號為jobspec的進程。

 重要提示:

     (1)Ctrl+C等組合鍵只能給在當前終端中運行的前臺進程發送信號,對于其他終端的進程或后臺進程是不能發送信號的。

     (2)有時通過kill命令發送信號給某些進程需要root權限,接收進程才會執行希望的操作,此時要通過sudo命令執行kill發送信號。

2.     如何處理信號

在執行過程中,當用戶按下組合鍵Ctrl+C或者使用kill命令發送TERM信號終止腳本的運行,那么臨時文件就不會刪除,這些殘留文件會占用大量的硬盤空間,同時會給用戶帶來困擾。

 我們可以讓運行的腳本在接收TERM信號時,自動地刪除這些臨時文件,因此需要實現一個自定義回歸函數來執行這些操作,而注冊TERM信號的這個回調函數就要通過trap命令來實現。

    trap的格式如下:

    trap cmd signa1 signal2…

其中,cmd可以是一系列命令或一個函數的名字,在它后面是一系列信號的數字或信號名。若cmd參數沒有指定,shell腳本在接收到這些信號時會執行它們的默認行為。

案例1 實現以上功能的代碼如下:

#!/bin/bash#使用當前腳本運行的進程PID創建一個唯一的文件TMPFILE=tmpfile.$$#定義收到信號時回調函數CleanUp(){if[ -f "$TMPFILE" ]then   echo   echo "Cleaning Up..."   #清除腳本產生的臨時文件   rm -f $TMPFILE 2 > /dev/null   echo "Done."   echofi#結束腳本程序的執行exit 2}#注冊新號回調函數CleanUptrap CleanUp 1 2 3 15#創建臨時文件echoecho "Creating temporary file $TMPFILE ..."echo 'date' > $TMPFILEecho#模擬一些工作echo "Script is running ..."echo -n "       "#打印進度條TIME=15until [ "$TIME" -eq 0 ]doecho -n "###"#每打印一次#號就睡眠一秒sleep 1#讓TIME的值減一,最終等于零時循環結束let TIME-=1done#執行到這里時,會清除臨時文件echoecho "Cleaning Up termporary file $TIMPFILE ..."rm -f $TMPFILE 2 > /dev/nullechoexit 0

案例2 在案例1是多個信號共用一個信號處理函數,若希望為信號HUP實現一個單獨的處理函數,用來重現初始化腳本,該如何實現?

#!/bin/bash#使用當前腳本運行的進程PID創建一個唯一的文件TMPFILE=tmpfile.$$#定義回調函數Init(){echoecho "Receive SIGHUP,Reinitialize script..."echo "Deleting temporary file,Creating new one..."rm -f $TMPFILE 2 > /dev/nullecho 'date' > $TMPFILEecho "Done."echo -n "     "TIME=15}#定義收到信號時回調函數CleanUp(){if[ -f "$TMPFILE" ]then   echo   echo "Cleaning Up..."   #清除腳本產生的臨時文件   rm -f $TMPFILE 2 > /dev/null   echo "Done."   echofi#結束腳本程序的執行exit 2}#注冊新號回調函數CleanUptrap CleanUp 2 3 15#為信號1注冊回調函數Inittrap Init 1#創建臨時文件echoecho "Creating temporary file $TMPFILE ..."echo 'date' > $TMPFILEecho#模擬一些工作echo "Script is running ..."echo -n "       "#打印進度條TIME=15until [ "$TIME" -eq 0 ]doecho -n "###"#每打印一次#號就睡眠一秒sleep 1#讓TIME的值減一,最終等于零時循環結束let TIME-=1done#執行到這里時,會清除臨時文件echoecho "Cleaning Up termporary file $TIMPFILE ..."rm -f $TMPFILE 2 > /dev/nullechoexit 0

案例3 是否可以在Shell腳本退出時,得到一個信號,從而處理某些特定的操作?

#!/bin/bash#這個回調函數會在腳本退出以前被調用quit_handler(){echoecho "In quit_handler():"echo "Script will exit."echo "Bye"echo}#注冊偽信號0點回調函數,使得在腳本退出以前可以做一些事情,使用EXIT和0的效果是一樣的trap quit_handler 0echo "These lines PRints before the /"trap/"--"echo "Even thought the Script see the /"trap/" first."echo#即使注釋exit命令,偽信號0也會產生exit 0

3.     忽略信號

當執行一個需要較長時間才能完成的腳本時,用戶可以通過組合鍵Ctrl+C來終止腳本的執行,但是如果用戶的腳本在執行一些關鍵性的操作,不希望被打斷,如備份或恢復瓷盤數據,就需要屏蔽用戶使用Ctrl+C組合鍵或使用kill命令發送的INT(interrupt)信號。

解決方案:只要把trap命令中的操作指定為空,就可以替換默認的退出操作,從而忽略INT信號。

#使用空字符串貨冒號屏蔽信號2 SIGINT

trap ‘’ INT

#冒號是bash的一個內建命令,它總是什么都不做并且總是返回0。

4.     定時器

案例1

如果希望用戶在指定的時間內輸入用戶名,否則腳本就退出執行,該如何實現?

#!/bin/bash#定義函數Expire_Handler用來捕捉SIGALARM信號Expire_Handler(){echo echo "Got SIGALARM signal,Waiting for Your info too long!"echo "Bye."#從腳本中以退出代碼14退出,用來表示接收到SIGALRM信號exit 14}#定義函數,用來設置一個定時器Start_Timer(){#如果沒有指定參數,默認為10秒local INTERVAL=${1:-10}#檢查參數大于0if [ $INTERVAL -gt 0 ]then   #15秒以后發送信號SIGALRM到腳本進程本身   sleep $INTERVAL && kill -s 14 $$ &   #記住后臺進程PID,用來殺死定時器   #如果用戶在最后期限以前輸入信息   TIMERPID=$!else echo "Error:Interval must be positive integer!"exit 1fi}#定義函數,用來殺死后臺進程,從而去除定時器Unset_Timer(){#首先殺死子進程kill 'pgrep -P $TIMERPID'#然后殺死父進程kill $TIMERPID}#設置定時器回調函數Expire_Handler來捕捉SIGALARM信號trap Expire_Handler 14echo echo "You have only 15 seconds to enter your info!"echo#把定時器設置為15秒到時間Start_Timer 15read -p "Please Enter your ID:" ID#如果用戶在最后期限以前輸入了信息,則移除定時器Unset_Timerechoecho "Your ID is: $id"echo "All Done."echoexit 0

5.     小結

信號也是進程間通信的一種方式,通過信號可以告訴程序某一個重要的時間正在發生。在腳本的執行過程中,由于信號可以在任何時候到達,會給原來的腳本增加一些相應的復雜性,所以在腳本中需要考慮可能接收到的信號,并添加處理這些信號的方法。

本章介紹了有關信號的內容,包括信號的概念,Shell編程中一些經常用到的信號,如何獲得當前平臺所支持的信號,發送信號和處理信號的方法,以及一些信號的應用。

本章的重要知識點包括:

(1)信號的兩種表達方式,數字和名字;

(2)如何查看所有的信號名和對應的數字;

(3)發送信號的方法;

(4)如何定義信號處理的函數;

(5)進程在收到一個信號時的三種處理信號的方式;

(6)忽略信號和重置信號處理函數的方法;

(7)信號的一些常用應用,如刪除臨時文件和設置定時器。


上一篇:PAT 1046

下一篇:第11章 其他常用工具

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 肇源县| 阿拉善右旗| 莲花县| 永宁县| 天台县| 永仁县| 宁德市| 进贤县| 贵定县| 兖州市| 方正县| 互助| 湘潭县| 浮梁县| 桃江县| 思茅市| 津南区| 嵊州市| 体育| 明水县| 宝坻区| 山阴县| 玉屏| 阿克苏市| 武夷山市| 丹巴县| 浦北县| 镇巴县| 黄山市| 青铜峡市| 东阳市| 察隅县| 宝坻区| 连江县| 华坪县| 夹江县| 宜章县| 西乌| 四会市| 同江市| 咸宁市|