我在 crontab 上设置了脚本,每 15 分钟运行一次。它通过相应的消息正确地向我发送邮件,但是当服务器出现故障时,重新启动命令 (/usr/share/tomcat5.5/bin/startup.sh) 不会重新启动 Tomcat,但是如果我手动运行此脚本,它重启!
*/15 * * * * /root/is_site_alive
#!/bin/bash
s=$(curl -o /dev/null --silent --head --write-out '%{http_code}\n' 'http://www.nononono.com')
if [ $s == "200" ]; then
echo 'java is UP' | mail -s "java is UP" mail@mail.com
else
/usr/share/tomcat5.5/bin/startup.sh
echo 'java is down - Restarting' | mail -s "Restarting" mail@mail.com
fi
编辑
当我记录从 crontab 运行的输出时,它说:
Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
At least one of these environment variable is needed to run this program
但是当我手动运行脚本时:
Using CATALINA_BASE: /usr/share/tomcat5.5
Using CATALINA_HOME: /usr/share/tomcat5.5
Using CATALINA_TMPDIR: /usr/share/tomcat5.5/temp
Using JRE_HOME: /usr/lib/jvm/java-6-sun/jre
似乎运行 crontab 的用户不了解 Java 路径。为什么会这样?
最佳答案
问题是 cron 作业不会像您通过终端登录时那样以您的用户身份运行。这是因为当您以实际用户身份登录时,您的用户 shell 配置文件(存储在 .profile
、.bash_profile
或 bashrc
)被加载到作为登录过程的一部分。因此,用户设置(例如系统路径)已加载到您的 session 中,而您甚至可能都没有意识到。
因此,当涉及到 cron 作业时,您的路径信息丢失了,因为 cron 任务实际上并不以您的身份登录,而只是以您的用户身份运行该过程。
因此,当您的 cron 作业明确指向此处的文件时:
/root/is_site_alive
登录时系统路径中包含的库、二进制文件和其他项目丢失。因此,您的 bash 文件中的进程基本上会丢失并且无法找到它们需要运行的项目。
解决此问题的一种快速而肮脏的方法是执行以下操作。首先从终端获取你的 $PATH
:
echo $PATH
输出应该是这样的:
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
现在,在你的 bash 脚本中——就在 #!/bin/bash
行之后——添加 $PATH
信息,如下所示:
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
s=$(curl -o /dev/null --silent --head --write-out '%{http_code}\n' 'http://www.nononono.com')
if [ $s == "200" ]; then
echo 'java is UP' | mail -s "java is UP" mail@mail.com
else
/usr/share/tomcat5.5/bin/startup.sh
echo 'java is down - Restarting' | mail -s "Restarting" mail@mail.com
fi
现在,当您运行该 bash 脚本时,您期望的路径值将就位。脚本应该按预期运行。
关于bash - 脚本在 crontab 中无法正常工作,但在我手动运行时可以正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24188770/