2010-09-10 111 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)