更新

更新

我有一个 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

相关内容