【问题标题】:Linux crontab doesnt launch a scriptLinux crontab 不启动脚本
【发布时间】:2010-09-11 00:50:06
【问题描述】:

我有这个用户 crontab(通过命令 crontab -e 访问):

# 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 服务正在运行,一切都很好###” 尽管“脚本”没有运行。

谢谢,

【问题讨论】:

    标签: bash shell cron crontab


    【解决方案1】:

    这是编写条件的更好方法:

    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
    

    通过使用ps -e -o comm,您可以避免做愚蠢的grep -v grep 事情,因为只有实际的进程名称出现在 ps 输出中,而不是参数。而grep -cFi 对匹配进行计数并为您提供一个数字,因此您不必处理管道的退出状态。

    此外,正如其他海报所暗示的那样,您应该通过设置 PATH 变量来启动此脚本。

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

    您可能希望也可能不希望将/usr/local/bin 放在该列表的开头,具体取决于您的系统。如果您不需要那里的任何东西,请不要这样做。

    最后一条建议:编写无需用户监督即可执行的脚本(例如 cron 作业)时,最好将 set -e 放在开头。如果任何命令失败,这会使它们无法成功退出。

    【讨论】:

      【解决方案2】:

      您需要将grep -v grep 放在 grep -i "$SERVICE" 之后。你现在拥有它的方式是保证是真实的。

      【讨论】:

      • 这也是惊人的脆弱(虽然并不罕见)。例如,如果其他用户在其名称中的任何位置运行带有“服务”的命令,您的脚本将认为一切正常。相反,请考虑实际测试服务已启动,例如通过尝试连接到它。
      【解决方案3】:

      这样检查管道的返回状态可能会有问题。您应该检查 $PIPESTATUS 数组,或者您可以通过管道将最终的 grep 输入 wc -l 以计算行数。

      【讨论】:

        【解决方案4】:

        cron 通常不会像用户帐户那样设置很多环境。您可能需要修改脚本才能正确设置。

        【讨论】:

          【解决方案5】:

          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
          

          (如果 Script.pl 是可执行的并且在 shebang 行中具有正确 perl 的路径,您可以再次删除 /usr/bin/perl 位。)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-02-06
            • 1970-01-01
            • 2020-04-22
            • 2013-02-06
            • 2019-10-18
            • 1970-01-01
            • 2020-01-01
            • 1970-01-01
            相关资源
            最近更新 更多