我有一个预定的脚本,它每小时对我们的 Subversion 存储库进行 svnsync 备份。我从根 crontab 中的一个条目运行它没有问题,但我决定我想从 /etc/cron.hourly 运行它而不是为了增加可见性(并且因为我们的一位工程师不小心删除了 crontab,因为他认为“crontab -r”的意思是“阅读 crontab ;-))
cron.hourly 脚本中的 svnsync 命令都失败,并显示一条消息,指出需要接受 SVN 存储库的 SSL 证书(这是用户第一次访问 SVN 存储库时以交互方式获得的消息,但是一旦证书我接受该消息不再出现)。
因此,在我看来,从 cron.hourly 运行脚本时,该脚本是在不同的用户环境下执行的,而不是通过根 crontab 运行时。谁能解释其中的区别?
更新:我应该提到我的发行版,我在 CentOS 5.1 上使用 anacron。
更新2:感谢到目前为止的建议;我认为这更像是一个颠覆问题。我总是尝试将我的环境封装到我的脚本中,但这里的问题是我不确定它在(或缺少)什么环境中使 SVN 在我运行我的脚本时要求接受 SSL 证书cron.hourly。我猜这与 run-parts 脚本的执行方式有关。
在 Debian/Ubuntu 系统上,cron.daily|weekly|montly 是从主 crontab 启动的。
另请记住,您可能可以在 /etc/cron.d/ 中放置一个 crontab 片段
如您所见,这种环境并没有什么特别之处。至少在 Debian/Ubuntu 上,它都是以 root 帐户运行的。
当我在脚本的最开始编写 cron 脚本时,我总是设置我的 PATH 和我将使用的其他环境变量,所以我可以确定它在任何环境中都能正常工作。
常规系统范围的 crontab 是特定用户的 crontab,它具有用户名字段,由
/etc/crontab
.在(每小时、每天、每周、每月)中使用脚本是为用户
/etc/cron.*
配置 crontab 的一种更清洁、更简单的方法(防止常见的语法错误),这是由在目录中运行脚本或程序来处理的。默认情况下,所有这些规则仍然在系统范围的 crontab 中定义(),所以它是一回事。root
run-parts
/etc/crontab
当 cron 作业由 处理时
run-parts
,更容易调试,因为您可以通过以下方式简单地测试哪些脚本将准确运行(尚未运行它们):您想使用“--config-dir”选项让它知道在哪里可以找到接受的证书(例如 ~/.subversion 默认情况下)。
也就是说,我几乎可以肯定你最好从 hooks/post-commit 脚本中调用 svnsync,正如其他地方所建议的那样。然后你的镜像总是同步的,而不是与你的主人在一小时前的位置同步。
我的第一个疯狂猜测是检查您的 HOME 变量。
在我的 Centos 系统上, man 5 crontab 说:
因此,如果您没有另外指定,root 的 crontab 将使用 /root 作为 HOME。但是在 /etc/crontab(通过 run-parts 运行 /etc/cron.hourly 的地方)中,HOME 设置为 /(并且 SHELL 设置为 /bin/bash 而不是 /bin/sh)。
我不知道 svnsync,但是 subversion 确实使用了一个 ~/.subversion/ 目录,所以这可能取决于 HOME。
在我的 RHEL 5.1 系统上,PATH 环境变量是从 /etc/crontab 设置的。顶部的所有东西都是被送入环境的东西。
如果你重新启动 cron,那么它第一次运行时(如果 from
/etc/crontab
或/var/spool/cron/$USER
)它会在 /var/log/cron 中记录下来。否则它只会注意到 cron.hourly 运行我的 crontab 设置如下:
你可以做的就是在 /etc/cron.hourly 中加入如下内容:
然后在文件出现时检查文件,并修改您的脚本(如果可以的话)以正确设置环境,或者编写一个简短的包装脚本,您的 crontab 将调用该脚本。
/var/log/messages
(或您的发行版的等价物)应该告诉您何时以及以哪个用户运行的命令的细节。永远不要假设环境中有任何东西。始终进行防御性编码。你有一个完整的文件来放置你想要的任何环境设置的东西。用它。
其他的可移植性并不多,我上次检查时(在 Debian 中),如果你想用你的东西创建一个包,建议将东西放在 cron.hourly (和其他)中,而不是直接放在 crontab 中。