最近用Python寫了一些數(shù)據(jù)統(tǒng)計的腳本,并使用crontab自動執(zhí)行,但是配置crontab總是要過幾個坑才行的,這里總結(jié)一下這次遇到的坑。
輸出
要將crontab命令的輸出記錄到日志文件中,可以使用重定向,不僅要重定向stdout也要重定向stderr,因為Python解釋器會將異常輸出到stderr。示例:
$HOME/path/to/script > $HOME/log/file 2>&1 &
環(huán)境變量
crontab會以用戶的身份執(zhí)行配置的命令,但是不會加載用戶的環(huán)境變量,crontab會設(shè)置幾個默認(rèn)的環(huán)境變量,例如SHELL、PATH和HOME等,一定要注意PATH可不是用戶自定義的PATH。
我們往往會在.bash_profile文件中定義一些全局的環(huán)境變量,但是crontab執(zhí)行時并不會加載這個文件,所以你在shell中正常執(zhí)行的程序,放到crontab里就不行了,很可能就是因為找不到環(huán)境變量了。要解決這個問題只能是自己加載環(huán)境變量了,可以在shell腳本中添加source $HOME/.bash_profile,或者直接添加到crontab中。
0 12 * * * source $HOME/.bash_profile && $HOME/path/to/script > $HOME/log/file 2>&1 &
路徑
我們在寫腳本時往往會使用相對路徑,但是在crontab執(zhí)行腳本時,由于工作目錄不同,就會出現(xiàn)找不到文件或者目錄不存在的問題。
解決方法是腳本中使用絕對路徑:
0 12 * * * /usr/local/bin/python /path/to/script > /var/log/file 2>&1 &
編碼
我寫的Python程序中輸出了一些中文(編碼是utf-8),在shell中直接執(zhí)行沒有問題,但是crontab執(zhí)行時出現(xiàn)了UnicodeEncodeError的錯誤,Google了一下發(fā)現(xiàn)這個問題不僅僅是在crontab中會出現(xiàn),在使用管道或者重定向的時候都會出現(xiàn)這個問題,原因是編碼不同。
在終端中直接執(zhí)行Python程序時,Python會將輸出內(nèi)容自動編碼為終端所使用的編碼,我使用的終端編碼是utf-8,所以不會出錯,輸出的內(nèi)容也是正常的。但是在使用管道或者重定向時,編碼格式為ascii,Python會用ascii編碼格式去encode輸出的字符串,但是字符串的編碼使用的時utf-8,所以會出現(xiàn)UnicodeEncodeError的錯誤。
解決方法:
方法一:在程序中可能輸出中文的字符串都加上encode('utf-8');
方法二:在crontab中加上PYTHONIOENCODING=utf-8,將Python的stdout/stderr/stdin編碼設(shè)置為utf-8。