我有一个 cron 作业,它运行一个 django 管理命令来清除我的邮件队列。结果发现它没有发送,几千名客户没有收到电子邮件。
知道这里发生什么事了吗?
我的 crontab 中有此行(并且在过去 3 年多的时间里一直如此。)
* * * * * /srv/grove_project/bin/cron.bash send_mail
当我由同一个用户手动运行它时,它可以工作。
/srv/grove_project/bin/cron.bash send_mail
在/var/log/syslog
那里
Sep 20 10:10:01 ~ CMD (/srv/grove_project/bin/cron.bash process_fulfillment_postback > /dev/null 2>&1)
Sep 20 10:10:01 ~ CMD (/srv/grove_project/bin/cron.bash send_mail )
Sep 20 10:10:01 ~ CMD (/srv/grove_project/bin/cron.bash monitor > /dev/null 2>&1)
其余命令运行良好。
是什么赋予了?
更新
更多信息:该命令的输出是:
/srv/grove_project/env/lib/python2.6/site-packages/django/conf/__init__.py:75: DeprecationWarning: The ADMIN_MEDIA_PREFIX setting has been removed; use STATIC_URL instead.
"use STATIC_URL instead.", DeprecationWarning)
INFO 2012-09-20 12:34:02,210 root 31267 ------------------------------------------------------------------------
以下是实现该功能的函数:
logging.info("-" * 72) #<--- this line printed
# if PAUSE_SEND is turned on don't do anything.
if not PAUSE_SEND:
send_all()
else:
logging.info("sending is paused, quitting.")
我没有看到“发送已暂停”消息,因此查看该send_all
功能
lock = FileLock("send_mail")
logging.debug("acquiring lock...") #<-- I don't see this line
由于我没有看到获取锁定的消息,它一定是FileLock
仅为 crontab 默默挂起?
答案1
将错误输出发送到日志文件。而不是这样:
* * * * * /srv/grove_project/bin/cron.bash send_mail
做这个:
* * * * * /srv/grove_project/bin/cron.bash send_mail > /tmp/cron.bash 2>&1
命令中的任何错误都应位于 /tmp/cron.bash 中。这告诉了你什么?
作为最佳实践,将 Cronjob 中的 STDOUT 和 STDERR 发送到某个地方始终是一个好主意。该 Cronjob 可能会向某个电子邮件地址(例如“root”)发送电子邮件。我敢肯定,收到 root 电子邮件的人不会喜欢它。
就我个人而言,我喜欢使用 /usr/bin/logger 将我的 cronjob 输出发送到 syslog。如果有问题,只需检查一下/var/log/messages
。
答案2
将其附加> /tmp/send_mail.log 2>&1
到你的 cron 的末尾,然后等待它再次失败,并查看send_mail.log
发生了什么。
自己调用脚本和crontab调用环境有什么区别?
Cron 在非常简约的环境下运行。
您可以将当前环境重定向到文件:
env > ~/env.full
然后在以下环境下运行你的工作:
* * * * * env - $(/bin/cat /home/yuji/env.full) /srv/grove_project/bin/cron.bash send_mail > /tmp/send_mail.log 2>&1