2010-09-10 119 views
0

我有這個用戶的crontab(通過命令crontab -e訪問):Linux的crontab的犯規啓動腳本

# m h dom mon dow command 
*/3 * * * *   sh /home/FRAPS/Desktop/cronCheck.sh 

腳本cronCheck.sh看起來像這樣:

#!/bin/sh 
SERVICE='Script' 

if ps ax | grep -v grep | grep -i "$SERVICE" > /dev/null 
then 
    echo "######## $SERVICE service running, everything is fine ##################\n" >> CronReport.txt 
else 
    echo "$SERVICE is not running. Launching it now\n" >> CronReport.txt 
    perl Script.pl 
fi 

當我啓動腳本(cronCheck.sh)來自它自己的目錄,它就像一個魅力一樣,但是當cron啓動它時,它總是「#$ SERVICE服務正在運行,一切正常###」 儘管'腳本'沒有運行。

感謝,

回答

2

下面就來寫一個更好的方法是有條件的:通過使用

services=$(ps -e -o comm | grep -cFi "$SERVICE") 
case "$services" in 
    (0) 
     # restart service 
    ;; 
    (1) 
     # everything is fine 
    ;; 
    (*) 
     # more than one copy is running 
    ;; 
esac 
你避免必須做愚蠢的 grep -v grep事情,因爲只有實際進程名稱出現在ps輸出中,而不是參數。並且 grep -cFi對比賽進行計數並給你一個數字,所以你不必處理管道的退出狀態。

另外,正如其他海報所暗示的,您應該通過設置PATH變量來引導此腳本。

PATH=/bin:/usr/bin:/sbin:/usr/sbin 
export PATH 

您可能會或可能不希望把/usr/local/bin在該列表的開始,取決於你的系統。不要這樣做,如果你從那裏不需要任何東西。

最後一條建議:在編寫將在沒有用戶監督的情況下執行的腳本(如cron作業)時,最好在開始處放置set -e。如果有任何命令失敗,這會使它們退出失敗。

1

檢查那樣的管道的返回狀態可能有問題。您應該檢查$ PIPESTATUS數組,或者您可以將最終的grep傳入wc -l來計算行數。

2

你需要把grep -v grepgrep -i "$SERVICE"。你現在的方式是保證是真實的。

+1

這也是令人驚訝的脆弱(雖然不是特別如此)。例如,如果其他用戶正在其名稱中的任何位置運行帶有「Service」的命令,則腳本會認爲一切正常。相反,實際上測試服務已經到了通過嘗試連接到它。 – telent 2010-09-10 16:53:13

1

cron通常不會像用戶帳戶那樣設置很多環境。您可能需要修改腳本才能正確設置事物。

1

Cron作業沒有得到與shell提示符相同的環境設置 - 這些設置通常是由shell在登錄時設置的 - 所以您希望在整個過程中使用絕對路徑而不是相對路徑。 (即,不要假設PATH環境變量將存在,或者在shell提示符下設置爲與您的相同,並且不要假設腳本將PWD設置爲您的主目錄等)。因此:

    在crontab條目
  • 取代sh/bin/sh(或刪除它,如果cronCheck.sh是可執行的,shebang行會做)。
  • 在cronCheck.sh中添加路徑到日誌文件和perl腳本。

cronCheck.sh應該結束了看起來像:

#!/bin/sh 
SERVICE='Script' 

if ps ax | grep -v grep | grep -i "$SERVICE" > /dev/null 
then 
    echo "######## $SERVICE service running, everything is fine ##################\n" >> CronReport.txt 
else 
    # Specify absolute path to a log file that's writeable for the user the 
    # cron runs as (probably you). Example: /tmp/CronReport.txt 
    echo "$SERVICE is not running. Launching it now\n" >> /tmp/CronReport.txt 

    # Specify absolute path to both perl and the script. Example: /usr/bin/perl 
    # and /home/FRAPS/scripts/Script.pl 
    /usr/bin/perl /home/FRAPS/scripts/Script.pl 
fi 

(同樣,你可以擺脫在/ usr/bin中/ perl的位,如果Script.pl是可執行文件,有路徑。在家當行權的perl)