我的脚本没有按照 cron 计划运行

我的脚本没有按照 cron 计划运行

我(在 Stack Exchange 的帮助下)制作了一个脚本,用于检查 Web 应用程序是否可用并重新启动 Web 应用程序守护进程,以便使其再次运行(通常在我工作之前会有所帮助)。它应该每小时运行一次。

我已将以下行添加到sudo crontab -e

0 * * * * bash /usr/local/bin/test.sh

内容test.sh

#!/bin/sh
HTTP_STATUS=$(lynx -head -source https://example.com |head -1 |awk '{print $2}')
calendar=$(date "+%d-%m-%Y - %H:%M")
LOG="Log is placed in /usr/local/bin/test.log"

if [ "$HTTP_STATUS" = "503" ]
then
    systemctl restart mydaemon

    echo "$calendar - site unavailable ($HTTP_STATUS). Daemon restarted." >> test.log
elif [ "$HTTP_STATUS" = "200" ]
then
    echo "$calendar - site available ($HTTP_STATUS)" >> test.log
else
    echo "$calendar - site status unknown ($HTTP_STATUS)" >> test.log
fi

我在 cron 中计划了另外两个脚本,它们工作得很好,只是它们在每个午夜运行。我的所有脚本都具有相同的权限和相同的所有者。

我的test.log文件不是每小时更新一次,所以我想脚本不会运行。运行脚本手动创建日志条目。

答案1

crontab 在与登录 shell 不同的环境中运行脚本;特别是,PATH 可能不同或未定义。

尝试在命令上使用绝对路径(lynx、head ...)您可以使用以下命令获取它们

which <command>

此外,您应该指定 test.log 的路径。

答案2

您的脚本运行得很好,但它写入test.log当前目录中调用的文件。由于您从未cd在脚本中,因此从技术上讲,当前目录位于任何位置,但它很可能是用户的主目录。

要写入test.log位于其他位置,可以cd写入脚本中的正确目录,或者test.log在重定向到文件时提供文件的完整路径。

另请注意,您对输出文件进行了许多不必要的重定向。如果全部语句的输出if应该附加到日志文件中,您也可以这样做

if ...; then
   ...
elif ...; then
   ...
else
   ...
if >>/path/to/test.log

这会将if语句内的所有输出重定向到文件。

或者如果全部脚本的输出应该重定向到日志文件,您也可以使用以下命令从 crontab 重定向

0 * * * * bash /usr/local/bin/test.sh >>/path/to/test.log

(一些 crontab 支持@hourly作为编写的快捷0 * * * *方式,顺便检查man 5 crontab一下你的系统)。

2>&1将标准输出重定向到文件后标记 on也可以重定向标准错误流(即... >/path/to/test.log 2>&1)。

此外,您已经/bin/sh在脚本行中,但您从 crontab 显式#!运行脚本。bash这很令人困惑。据我所知,bash您的脚本中没有任何特定内容,因此要么从 crontab 运行它/bin/sh,要么只是使其可执行并且在 crontab 的命令行上指定一个解释器来运行它。


我对你的剧本的看法:

#!/bin/sh

now=$(date "+%d-%m-%Y - %H:%M")
logfile=/usr/local/bin/test.log

status=$( lynx -head -source 'https://example.com' | awk 'FNR == 1 { print $2 }' )

case $status in
    503)
        systemctl restart mydaemon
        message='Daemon restarted, site was unavailable'
        ;;
    200)
        message='Site is available'
        ;;
    *)
        message='Site status is unknown'
esac

printf '%s: %s (status=%s)\n' "$now" "$message" "$status" >>"$logfile"

相关内容