如何在 crontab 中进行测试
Posted
技术标签:
【中文标题】如何在 crontab 中进行测试【英文标题】:How to test things in crontab 【发布时间】:2010-11-18 22:44:54 【问题描述】:这一直发生在我身上: 1)我写了一个脚本(ruby,shell等)。 2)运行它,它的工作原理。 3)把它放在 crontab 中,让它在几分钟内运行,所以我知道它从那里运行。 4)没有,没有错误痕迹,回到第2步或第3步1000次。
当我在 crontab 中的 ruby 脚本失败时,当我像这样通过管道输出时,我真的不知道为什么它会失败:
ruby script.rb >& /path/to/output
我得到了脚本的输出,但我没有得到任何错误,也没有得到来自 bash 的错误(比如找不到 ruby 或文件不存在)
我不知道设置了哪些环境变量以及是否有问题。事实证明,要从 crontab 运行 ruby 脚本,您必须导出大量环境变量。
我有没有办法让 crontab 像 我自己从终端运行它一样运行脚本?
调试时,我必须重置计时器并返回等待。非常耗时。
如何更好地测试 crontab 中的内容或避免这些问题?
【问题讨论】:
红宝石在哪里?是否在 /usr/bin 等系统路径中?看看:ubuntuforums.org/showthread.php?t=190671,看看有没有和你看到的类似的消息。这是 ruby 在 cron 可以看到的路径之外的情况。 我的 crontab 中作业的错误(实际上是任何输出)会通过电子邮件发送给我,即 crontab 的所有者。不记得我需要更改任何设置才能发生这种情况...您是否检查过运行 cronjob 的系统上是否有任何电子邮件? 如何将您的输出定向到系统日志? angryruby.blogspot.com/2007/08/ruby-and-syslog.html 请注意,">&" 不是 sh 语法(它是 csh)。您希望“ruby script.rb >/path/to/output 2>&1”将标准输出和标准错误重定向到该文件。或者,“ruby script.rb 2>&1 | mailx -s subject you@example.com” 【参考方案1】:“有没有办法让 crontab 像我自己从终端运行一样运行脚本?”
是的:
bash -li -c /path/to/script
来自手册页:
[vindaloo:pgl]:~/p/test $ man bash | grep -A2 -m1 -- -i
-i If the -i option is present, the shell is interactive.
-l Make bash act as if it had been invoked as a login shell (see
INVOCATION below).
【讨论】:
很好的答案,当需要一个与从命令行执行相同的环境时,这是从 crontab 执行任务的适当方式。【参考方案2】:生日,
cron 的一个基本问题是你得到了一个由 cron 设置的 minimal 环境。事实上,你只得到四个 env。 var 的集合,它们是:
SHELL - 设置为 /bin/sh LOGNAME - 设置为 /etc/passwd 中的用户 ID HOME - 设置为您的主目录。在 /etc/passwd 中找到 PATH - 设置为“/usr/bin:/bin”就是这样。
但是,您可以做的是拍摄所需环境的快照并将其保存到文件中。
现在让你的 cronjob 源成为一个简单的 shell 脚本来获取这个环境。文件,然后执行你的 Ruby 脚本。
顺便说一句,有一个包装器来源一个公共环境。 file 是为多个 cronjobs 强制执行一致环境的绝佳方式。这也强制执行了 DRY 原则,因为它只为您提供了一个点来根据需要更新内容,而不必搜索一堆脚本并搜索特定字符串,例如,如果日志位置已更改或现在有不同的实用程序被使用,例如gnutar 而不是香草焦油。
实际上,该技术非常成功地与 The Build Monkey 一起使用,它用于为世界几家主要航空公司通用的主要软件项目实施持续集成。每天多次检查和构建 3,500kSLOC,每天运行一次超过 8,000 次回归测试。
HTH
'Avahappy,
【讨论】:
【参考方案3】:从 ruby 脚本内部运行一个“设置”命令,从 crontab 中触发它,您会确切地看到设置了什么,没有设置什么。
【讨论】:
【参考方案4】:要找出 cron 运行作业的环境,请添加以下 cron 作业:
echo "\nenv\n" && env|sort ; echo "\nset\n" && set; | /usr/bin/mailx -s 'my env' you@example.com
或者将输出发送到文件而不是电子邮件。
【讨论】:
【参考方案5】:您可以编写一个包装脚本,例如称为rbcron
,它看起来像:
#!/bin/bash
RUBY=ruby
export VAR1=foo
export VAR2=bar
export VAR3=baz
$RUBY "$*" 2>&1
这会将标准错误从 ruby 重定向到标准输出。然后在 cron 作业中运行 rbcron
,标准输出包含 ruby 的 out+err,但也包含 rbcron 本身存在的“bash”错误。在您的 cron 条目中,重定向 2>&1 > /path/to/output
以获取输出+错误消息以转到 /path/to/output。
【讨论】:
将 VAR1 等和值更改为您需要为 ruby 导出的任何值。我没有这些答案。【参考方案6】:如果您真的想以自己的身份运行它,您可能需要从一个 shell 脚本调用 ruby,该脚本获取您的 .profile
/.bashrc
等。这样它就会拉入您的环境。
但是,缺点是它没有与您的环境隔离,如果您更改它,您可能会发现您的 cron 作业突然停止工作。
【讨论】:
Sourcing .profile/.bashrc 将设置与从该文件设置的环境变量相同的环境变量,但对于正在运行的进程不会“无法与您的环境隔离”,但您是对 - 它会在您的 HOME 目录中创建一个文件的依赖项。以上是关于如何在 crontab 中进行测试的主要内容,如果未能解决你的问题,请参考以下文章
django + celery - 如何在我的 django 应用程序中为 celery 设置 crontab 计划?