我(在 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"