1. 程式人生 > >Shell指令碼執行超時怎麼辦?

Shell指令碼執行超時怎麼辦?

Shell

在Shell裡會有一種不太常見的情況,就是指令碼有時候會出現超時的現象。一般來說遇到這種問題,我們都會簡單粗暴的採用下面這種指令碼來當“超時看門狗“:

這個指令碼搭配兩個變數使用的話,監控一點小程式碼還算OK,但是它的邏輯還是比較粗糙,比如如果在這個指令碼執行的時候,又有了一個新的process在後臺啟動,那麼kill掉的就是新的process,而本應該停止的指令碼還是在後臺肆無忌憚的跑著。

為了不濫殺無辜,所以遇到這種情況,就要使用timeout命令,具體的用法請自行#man timeout,這個命令在centos 6裡就是自帶的。

假設我們要ping www.baidu.com ,同時要求“若超過了5秒沒有反應,就停止這個任務”。那麼就是用命令:#timeout 5s ping www.baidu.com

,效果如圖:

從26秒到31秒,的確達到了5秒就跳出的效果。

牛刀小試結束,那麼現在我們就來進化一下我們之前的那個MQ指令碼,但是那個MQ指令碼有點理想化了,裡面忘記了新增“超時監控”以及“重啟失敗的話會發郵件提醒運維人員”這兩個功能,在這裡我們就把上面兩個短板補齊。

首先,我們先執行一下看看這個MQ看門狗指令碼需要執行的時間:

指令碼

從上面可見整個指令碼執行大約需要13秒,那麼我們考慮到其他因素設定超時時間為20秒,執行效果如圖:

返回碼是0,那麼再看看如果因為超時而停止的返回碼是多少呢?

返回碼

可見由於超時停止的返回碼是124(ctrl+c手動退出的返回碼是130),那麼整個指令碼就很好寫了,如下:

然後在crontab裡直接執行這個指令碼就好了。

補充說明之一,在文中測試timeout命令的時候,我使用了ping,其實這個是不嚴謹的,因為unix的ping預設會無限重複,所以#timeout 3s ping www.baidu.com 不管有沒有網路連線都會超時。這裡最好的例子是看看#timeout 3s sleep 1#timeout 3s sleep 5的區別。

補充說明之二,在shell腳本里,timeout後面若跟函式的話是無效的!