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都要使用絕對路徑。(這一點一定要注意,搞了一下午就栽在這上了)