我的 python 脚本和 cron 作业有什么问题?

What is wrong with my python script and cron job?

我有这个 python 脚本来检查 MySQL 和 Apache 等服务,如果其中一些出现故障,它会重新启动:

import subprocess
import smtplib

_process = ['mysql', 'apache2']
for _proc in _process:
    p = subprocess.Popen(["service", _proc, "status"], stdout=subprocess.PIPE)
    output, err = p.communicate()
    print "*** check service "+_proc+" ***\n"
    if 'Active: active (running)' in output:
        print _proc+" is working!"
    else:
        print "Ouchh!! "+_proc+" again is down."
        output = subprocess.Popen(["service", _proc, "start"])
        print "*** The service "+_proc+" was restarted ***\n", output

        print "*** sending email ***\n"
        server = smtplib.SMTP('smtp.gmail.com', 587)
        server.ehlo()
        server.starttls()
        _from = "from@email.co"
        _to = "to@email.co"
        _cc = ["another@email.co"]
        _pass = "xxxxxx"
        server.login(_from, _pass)
        msg = "\r\n".join([
            "From: "+_from,
            "To: "+_to,
            "CC: "+",".join(_cc),
            "Subject: Ouchh!! "+_proc+" again is down.",
            "",
            "Again " + _proc + " is down. The service was restarted!!"
        ])
        server.sendmail(_from, _to, msg)
        server.quit()
        print "*** email send ***\n"

当我执行以下命令时,它在我的控制台中工作正常:

python /home/check-services.py

一切看起来都很好。我尝试在 webmin 服务器中设置 cron 作业,它应该每分钟执行一次,但事实并非如此。这是 cron 的日志:

(root) CMD (python /home/check-services.py) 每分钟,就像我们已经配置好了一样。

我没有看到任何异常,但它仍然无法正常工作。感谢您的帮助。

Python 版本 2.7.

编辑: 我刚刚在 /var/email/root 中看到了电子邮件,它显示:

Traceback (most recent call last):
  File "/home/check-services.py", line 77, in <module>
    p = subprocess.Popen(["service", _proc, "status"], stdout=subprocess.PIPE)
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

问题是 service 不在 cron 进程的 $PATH 中列出的任何目录中。

有很多解决方案。一种解决方案是在 .Popen() 调用中指定 service 的完整路径。在我的电脑上,即 /usr/sbin/service.

试试这个:

p = subprocess.Popen(
    ["/usr/sbin/service", _proc, "status"], stdout=subprocess.PIPE)

另一个解决方案是在您的 crontab 中指定不同的 $PATH:

* * * * * PATH=/bin:/usr/bin:/sbin:/usr/sbin /usr/bin/python /home/check-services.py