shell 指令碼實現的守護程式

劉秋杉發表於2015-03-05

轉載自http://blog.sina.com.cn/s/blog_4c451e0e0100giqg.html



# #! 不是註釋符,而是指定指令碼由哪個直譯器來執行,

# #! 後面有一個空格,空格後面為直譯器的全路徑且必須正確。
#! /bin/ash

PRO_PATH=""
# testpro 為要守護的可執行程式,即保證它是一直執行的
PROGRAM="testpro"

# 此指令碼一直不停的迴圈執行,while <條件> 與 do 放在一行上要在條件後加分號
# if、then、while、do等關鍵字或命令是作為一個新表示式的開頭,
# 一個新表示式之前的表示式必須以換行符或分號(;)來結束

# 如果條件不是單個常量或變數而是表示式的話,則要用[]括起來
# while、until與for迴圈皆以do開始以done結束構成迴圈體
while true ; do
# 休息10秒以確保要看護的程式執行起來了,這個時間因實際情況而定
    sleep 10
# 單引號''中的$符與\符沒有了引用變數和轉義的作用,但在雙引號""中是可以的!
# 單引號中如果還有單引號,則輸出時全部的單引號都將去掉,單引號括住的內容原樣輸出。
# 例:echo 'have 'test'' --> have test
# ps aux --> a 為顯示其他使用者啟動的程式;
#                 u 為顯示啟動程式的使用者名稱與時間;
#                 x 為顯示系統屬於自己的程式;
# ps aux | grep 可執行程式名 --> 在得到的當前啟動的所有程式資訊文字中,
#                                            過濾出包含有指定文字(即可執行程式名字)的資訊文字行
# 注:假設 ps aux | grep 可執行程式名 有輸出結果,但輸出不是一條信而是兩條,
# 一個為查詢到的包含有指定文字(即可執行程式名字)的資訊文字行(以換行符0x10結尾的文字為一行),
# 一個為 grep 可執行程式名 ,即把自己也輸出來了,
# 所這條資訊是我們不需要的,因為我們只想知指定名字的可執行程式是否啟動了

# grep -v 指定文字 --> 輸出不包含指定文字的那一行文字資訊
# wc -l --> 輸出檔案中的行數(-l --> 輸出換行符統計數)

# ps aux | grep $PROGRAM | grep -v grep | wc -l --> 如果有指定程式名的程式啟動的話,結果大於壹
    PRO_NOW=`ps aux | grep $PROGRAM | grep -v grep | wc -l`

# 整數比較:-lt -> 小於,-le -> 小於等於,-gt -> 大於,-ge -> 大於等於,-eq ->等於,-ne -> 不等於
# if [條件] 與 then 放在一行上要在條件後加分號
# 如果當前指定程式啟動的個數小於壹的話
    if [$PRO_NOW -lt 1]; then
# 0 -> 標準輸入,1 -> 標準輸出,2 - > 標準錯誤資訊輸出
# /dev/null --> Linux的特殊檔案,它就像無底洞,所有重定向到它的資訊資料都會消失!

# 2 > /dev/null --> 重定向 stderr 到 /dev/null,1 >& 2 --> 重定向 stdout 到 stderr,
# 直接啟動指定程式,且不顯示任何輸出
# 可執行程式後面加空格加&,表示要執行的程式為後臺執行

        ./$PROGRAM 2>/dev/null 1>&2 &
# date >> ./tinfo.log --> 定向輸出當前日期時間到檔案,新增到檔案尾端,如果沒有檔案,則建立這個檔案 
        date >> ./tinfo.log
# echo "test start" >> ./tinfo.log --> 定向輸出 test start 新增到檔案尾端
        echo "test start" >> ./tinfo.log
# if 分支結構體結束
    fi

# 基本與上面的相同,就是多了一個 grep T,其結果為過濾出含 T 字元的資訊行
# T --> 程式已停止,D --> 不可中斷的深度睡眠,R --> 程式執行或就緒,S --> 可接收訊號的睡眠,
# X --> 已完全死掉,Z --> 已完全終止
    PRO_STAT=`ps aux|grep $PROGRAM |grep T|grep -v grep|wc -l`

# 如果指定程式狀態為已停止的資訊大於零的話
    if [ $PRO_STAT -gt 0 ] ; then
# killall --> 用名字方式來殺死程式,-9 --> 即發給程式一個訊號值為9的訊號,即SIGKILL(非法硬體指令)
# 也可以不指定訊號,預設為SIGTERM,即訊號值為15
        killall -9 $PROGRAM
        sleep 2
        ./$PROGRAM 2>/dev/null 1>&2 &
        date >> ./tinfo.log
        echo "test start" >> ./tinfo.log
    fi
# while、until與for迴圈皆以do開始以done結束構成迴圈體
done
# exit 用來結束指令碼並返回狀態值,0 - 為成功,非零值為錯誤碼,取值範圍為0 ~ 255。

exit 0




轉自維基百科http://zh.wikipedia.org/wiki/%E5%AE%88%E6%8A%A4%E8%BF%9B%E7%A8%8B

        

        通常,守護程式沒有任何存在的父程式(即PPID=1),且在UNIX系統程式層級中直接位於init之下。守護程式程式通常通過如下方法使自己成為守護程式:對一個子程式執行 fork,然後使其父程式立即終止,使得這個子程式能在 init 下執行。這種方法通常被稱為“脫殼”。



轉自百度百科:http://baike.baidu.com/view/53123.htm

守護程式,也就是通常說的Daemon程式,是Linux中的後臺服務程式。它是一個生存期較長的程式,通常獨立於控制終端並且週期性地執行某種任務或等待處理某些發生的事件。守護程式常常在系統引導裝入時啟動,在系統關閉時終止。Linux系統有很多守護程式,大多數服務都是通過守護程式實現的,同時,守護程式還能完成許多系統任務,例如,作業規劃程式crond、列印程式lqd等(這裡的結尾字母d就是Daemon的意思)。
由於在Linux中,每一個系統與使用者進行交流的介面稱為終端,每一個從此終端開始執行的程式都會依附於這個終端,這個終端就稱為這些程式的控制終端,當控制終端被關閉時,相應的程式都會自動關閉。但是守護程式卻能夠突破這種限制,它從被執行開始運轉,直到整個系統關閉時才退出。如果想讓某個程式不因為使用者或終端或其他地變化而受到影響,那麼就必須把這個程式變成一個守護程式。

相關文章