1. 程式人生 > >crontab 中 python 指令碼執行失敗的解決方法

crontab 中 python 指令碼執行失敗的解決方法

寫伺服器程式的免不了要經常和 crontab 打交道,定時執行一些指令碼什麼的。大部分情況下都是 bash 的一些 shell 指令碼,但 shell 我不是很熟悉,於是在很多情況下都直接寫 Python 指令碼來搞定它。今天寫了一個操作 PostgreSQL 資料庫的 Python 指令碼,放到 crontab 中定時執行的時候,時間到了卻沒有任何反映。但是如果在命令列下直接執行的話,沒有任何問題。

動態展示日誌的命令:

# tail -f /var/log/cron

首先看看 crontab 的日誌(/var/log/cron),日誌中顯示指令碼定時執行了。那麼一定是在 crontab 執行該指令碼的時候報錯。直接在 Python 指令碼中從第一行開始寫一個大大的 try 模組,顯示一下 Exception 的內容。果然,抓到了…… 錯誤日誌顯示顯示 Python 找不到 libpq.so.5 這個 PostgreSQL 的庫。

原來 crontab 的執行環境和我們用 root 登入進去的環境都是不同的,需要在執行 Python 指令碼前重新設定一下執行的環境變數如 LD_LIBRARY_PATH。這下比較好辦了,直接寫一個 shell 指令碼,設定一下環境變數,再呼叫 Python 吧。 libpq.so.5 這個庫我是裝在 /usr/local/pgsql/lib 中。最後的指令碼如下:

搞定,crontab 又跑得歡快起來了。

折騰了一個上午,寫下來備忘。

本地測試:

要執行的python指令碼:

config.py

'''
Created on Sep 14, 2012

@author: dashan.yin
'''
smtpserver='smtp.domainname.com'
smtpuser='
[email protected]
' smtppass='pwd' smtpport='25'

sendmail.py
#!usr/bin/env python
#coding: utf-8

import smtplib, config, email, sys
from email.Message import Message

def connect():
    "connect to smtp server and return a smtplib.SMTP instance object"
    try:
        server = smtplib.SMTP(config.smtpserver, config.smtpport)
        server.ehlo()
        server.login(config.smtpuser, config.smtppass)
    except Exception:
        print Exception
        print 'Error - connect failed'
    else:
        print "connect success!"
        return server
    
def sendmessage(server, to, subj, content):
    "using server send a email"
    msg = Message()
    msg['Mime-Version'] = '1.0'
    msg['From'] = config.smtpuser
    msg['To'] = to
    msg['Subject'] = subj
    msg['Date'] = email.Utils.formatdate()          # curr datetime, rfc2822
    msg.set_payload(content)
    try:
        failed = server.sendmail(config.smtpuser, to, str(msg))   # may also raise exc
    except Exception , ex:
        print Exception, ex
        print 'Error - send failed'
    else:
        print "send success!"

if __name__ == "__main__":
    to = "
[email protected]
" subj = "test" text = u"測試python傳送郵件程式" server = connect() sendmessage(server, to, subj, text)

shell指令碼:

sendmail.sh

#!/bin/sh
/usr/local/bin/python /usr/local/sbin/sendmail.py

定時設定:
crontab -u root -e

*/1 * * * * sh /usr/local/sbin/sendmail.sh

然後這樣就可以定時發郵件了。根據設定是每分鐘發一封!

常見的問題:

1.sendmail.sh sendmail.py是否有可執行許可權,如果沒有的話執行下面命令:

chmod +x sendmail.sh/sendmail.py

2.sendmail.sh sendmail.py都要使用絕對路徑。(這一點一定要注意,搞了一下午就栽在這上了)