为什么我的命令行无法在定时任务中运行?

5

我有一个perl脚本(属于XMLTV家族的“抓取器”,具体来说是tv_grab_oztivo)。

我可以像这样成功运行它:

/sw/bin/perl /path/to/tv_grab_oztivo --output /path/to/tv.xml

我使用完整路径来消除工作目录问题,权限不应该是个问题。
所以,如果我从终端(Mac OSX)运行它,它就可以正常工作。
但是当我将其设置为通过cron作业运行时,似乎什么都没有发生。没有创建任何输出等。
据我所见,crontab 没有任何问题,因为如果我用 helloworld.pl 替换实际脚本,它会在正确的时间运行得很好。
那么,我该如何调试?我可以从两种情况下查看 %ENV,发现环境差异很大,但我还能采取哪些方法进行调试?我怎样才能查看 cron 作业的输出,这可能是一些 Perl 的 "die" 消息或 shell 中的 "not found" 消息等?
或者,我应该尝试以某种方式给 cron 版本的命令提供与我的运行环境相同的环境?
5个回答

8

通常情况下,由于在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

它正在工作。谢谢你。最后,我只是将PERL5LIB和PATH添加到$ENV中,一切都很好。 - AmbroseChapel

3

如果你正在查看两种情况下的%ENV,在你的Perl脚本中,我建议作为第一步将%ENV设置为cron工作中的值,然后尝试从命令行运行它。你可能需要执行自己一次,以完全控制:

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中设置。


1
谢谢你的帮助,你在帮助我方面真的和 Pax 平起平坐,但我只能选择一个正确答案,抱歉。 - AmbroseChapel

0

有时候,如果您无法弄清楚命令行出了什么问题,最简单的解决方法是将整个过程转换为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运行时使用的环境变量不同。


0

我会通过绝对路径从cron命令运行一个简单的shell脚本。 在该脚本内部,我会确保将stdout和stderr捕获到已知(或可知)的文件中。我还会确保设置足够的环境变量。在Unix上,当您通过cron运行命令时,几乎没有设置任何环境变量 - 我不确定MacOS X是否也是如此。问题的标准罪魁祸首是PATH。我有一个单独的.cronfile,它足以设置我的工作环境,通常不会出现问题 - 这类似于.profile


-1

cron通常捕获标准输出和错误输出,并将任何输出以电子邮件的形式发送给crontab所有者。

你是否仔细检查了你的crontab条目,确保它是有效的并会在正确的时间执行?

确保脚本不需要设置任何环境变量。否则,请将其包装在另一个(bash)脚本中,在其中可以设置其他脚本所期望的环境变量。


你确认了你的crontab条目,以确保它是有效的并且会在正确的时间执行吗?--是的。我已经确认过了。 - AmbroseChapel
没关系,我只是想再确认一下。Crontab语法很棘手,很容易出错。 - lothar
如果您没有收到cron输出的邮件,您可以在crontab顶部使用MAILTO=someone@example.com来更改输出的接收者。只需确保您的本地邮件程序正常工作即可。 - preaction

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接