为什么我的命令行不能从cron运行?
我有一个Perl脚本(XMLTV“抓取器”家族的一部分,特别是tv_grab_oztivo
)。为什么我的命令行不能从cron运行?
我可以成功地这样运行:
/sw/bin/perl /path/to/tv_grab_oztivo --output /path/to/tv.xml
我使用的完整路径的一切,以消除工作目录的问题。权限不应该是一个问题。
所以,如果我从终端(Mac OSX)运行它,它工作得很好。
但是当我将它设置为通过cron作业运行时,根本没有任何事情发生。没有输出创建等
据我所知,没有任何错误的crontab,因为如果我用实际脚本替换helloworld.pl,它在正确的时间运行得很好。
那么,我能做些什么来调试?在这两种情况下,我可以看到%ENV
这个环境非常不同,但是我还可以采取其他哪些方法进行调试?我怎样才能看到cron作业的输出,这可能是某种perl“死”消息或shell中的“未找到”消息或其他东西?
或者我应该试图以某种方式让命令的cron版本与它运行时的环境相同?
这是经常因为在cron下运行时没有获得完整的环境。最好的办法是使用命令捕获输出中:
(/sw/bin/perl /path/to/tv_grab_oztivo ...) >/tmp/qq 2>&1
,然后看看/tmp/qq
。
如果它变成是一个缺少的环境,那么你可能需要把:
. ~/.profile
或类似的东西,到你的cron作业的执行链,如:
(. ~/.profile ; /sw/bin/perl /path/to/tv_grab_oztivo ...) >/tmp/qq 2>&1
cron通常捕获stdout和stderr的输出并将任何输出发送到crontab所有者。
您是否仔细检查了您的crontab条目以确保它是有效的并且将在正确的时间执行?
确保该脚本不需要任何环境变量集。否则,将其包装在另一个(bash)脚本中,您可以在其中设置其他脚本所期望的环境变量。
如果您在查看两种情况下的%ENV,我建议您作为perl脚本的第一步,将%ENV设置为cron作业中的内容,然后尝试从命令行。您可能需要一次exec的自己,这才会完全控制:
BEGIN {
if (exists $ENV{something_in_your_env_not_in_cron}) {
%ENV = (...);
exec $^X, $0, @ARGV;
}
}
现在试着运行它,并查看是否有什么可以做,以对其进行调试(包括如果需要的perl下运行-d)。很可能,您会发现最终一次将项目添加回%ENV,直到它奇迹般地开始工作(LD_LIBRARY_PATH对此很好,但对于Oracle或DB2应用程序,ORACLE_HOME或DB2HOME也可能是不错的选择)。然后,您可以在脚本中或在crontab中设置变量。
我会通过cron命令的绝对路径运行一个简单的shell脚本。 在该脚本中,我确保将stdout和stderr捕获到已知(或可知)文件中。我也会确保你的环境已经足够。在Unix上,当你通过cron运行一个命令时几乎没有环境设置 - 我不确定MacOS X.问题的标准问题是PATH。我有一个单独的.cronfile
,它使我的工作环境足以让我通常没有问题 - 这是.profile
的模拟。
有时候,如果你不能弄清楚你的命令行出了什么问题,最简单的方法就是把整个事情变成一个shell脚本。理想情况下,你不应该有这样做,但它可以是解决问题的最快方法。
文件:/files/cron1.sh
#!/bin/sh
/sw/bin/perl /path/to/tv_grab_oztivo --output /path/to/tv.xml
然后在cron:
/files/cron1.sh
这使您可以测试脚本独立的cron。请记住,您的登录shell使用不同于cron的环境变量运行。
“您是否仔细检查了您的crontab条目以确保它是有效的,并且会在正确的时间执行?” - 是的。我是这么说的。 – AmbroseChapel 2009-04-23 02:56:26
没关系,我只是想仔细检查一下。 crontab的语法很棘手,很容易弄错。 – lothar 2009-04-23 03:11:25
如果您没有收到邮寄给您的cron输出,您可以使用crontab顶部的MAILTO = [email protected]来更改输出的内容。只要确保您的本地邮件工程。 – preaction 2014-05-14 06:15:39