为什么我的命令行不能从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)脚本中,您可以在其中设置其他脚本所期望的环境变量。

+0

“您是否仔细检查了您的crontab条目以确保它是有效的,并且会在正确的时间执行?” - 是的。我是这么说的。 – AmbroseChapel 2009-04-23 02:56:26

+0

没关系,我只是想仔细检查一下。 crontab的语法很棘手,很容易弄错。 – lothar 2009-04-23 03:11:25

+0

如果您没有收到邮寄给您的cron输出,您可以使用crontab顶部的MAILTO = [email protected]来更改输出的内容。只要确保您的本地邮件工程。 – preaction 2014-05-14 06:15:39

如果您在查看两种情况下的%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的环境变量运行。