脚本在crontab中无法正常工作,但在我手动运行时有效

时间:2014-06-12 15:53:01

标签: bash tomcat crontab

我这是在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路径。为什么会这样?

3 个答案:

答案 0 :(得分:5)

问题是cron作业与您通过终端登录时的用户完全不同。这是因为当您以实际用户身份登录时,存储在.profile.bash_profilebashrc中的用户shell配置文件将作为登录过程的一部分加载。因此,您可能甚至不知道的会话中会加载用户设置(例如系统路径)。

因此,当涉及到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脚本时,您的预期路径值将会到位。脚本应按预期运行。

答案 1 :(得分:2)

问题是使用crontab的经典问题。当您登录到类似unix的系统时,您的shell至少会读取您的配置文件和/或系统配置文件,并取决于shell其他init文件。这些init文件通常设置PATH和各种环境字符串。

但是当通过crontab启动shell时,不会发生这些初始化。所以你必须:

  • 要么提供适当的初始化文件(不是真正推荐的,但可以是快速解决方法)
  • 或仔细设置所有相关环境变量并对/ bin和/ usr / bin之外的所有命令使用绝对路径(通过变量)

示例:

#! /bin/sh
JAVA_HOME=/path/to/java/home
JAVA=/path/to/java/bin/java

$(JAVA) -jar app.jar param1 param2

答案 2 :(得分:0)

另一种有效的解决方案

如果你的用户有一个主目录并且有一些环境变量,例如 /homedir/user1/ 那么你可以应用这个

#!/bin/ash
source $HOME/.bash_profile

或者这取决于 distrib,也许你必须添加这个:

#!/bin/ash
source $HOME/.profile

使用“源”行,您将可以访问用户的环境变量。

或者你可以在 cron 文件中指定:

*/15 * * * * source $HOME/.bash_profile; /root/is_site_alive

最重要的一点是通过复制一些环境变量来避免错误。

HOME 是 POSIX 标准,即使您通过 cron 作业执行脚本也会设置。 LOGNAME 也是 posix 标准,应该用来代替 USER。