最近用Python寫了一些數據統計的腳本,並使用crontab自動執行,可是配置crontab老是要過幾個坑才行的,這裏總結一下此次遇到的坑。shell
要將crontab命令的輸出記錄到日誌文件中,可使用重定向,不只要重定向stdout
也要重定向stderr
,由於Python解釋器會將異常輸出到stderr
。示例:bash
$HOME/path/to/script > $HOME/log/file 2>&1
crontab會以用戶的身份執行配置的命令,可是不會加載用戶的環境變量,crontab會設置幾個默認的環境變量,例如SHELL、PATH和HOME等,必定要注意PATH可不是用戶自定義的PATH。編碼
咱們每每會在.bash_profile
文件中定義一些全局的環境變量,可是crontab執行時並不會加載這個文件,因此你在shell中正常執行的程序,放到crontab裏就不行了,極可能就是由於找不到環境變量了。要解決這個問題只能是本身加載環境變量了,能夠在shell腳本中添加source $HOME/.bash_profile
,或者直接添加到crontab中。日誌
0 12 * * * source $HOME/.bash_profile && $HOME/path/to/script > $HOME/log/file 2>&1
咱們在寫腳本時每每會使用相對路徑,可是在crontab執行腳本時,因爲工做目錄不一樣,就會出現找不到文件或者目錄不存在的問題。code
解決方法是腳本中使用絕對路徑或者在執行程序前切換工做目錄,例如直接在crontab命令中切換工做目錄:crontab
0 12 * * * source $HOME/.bash_profile && cd $HOME/path/to/workdir && ./script > /HOME/log/file 2>&1
我寫的Python程序中輸出了一些中文(編碼是utf-8),在shell中直接執行沒有問題,可是crontab執行時出現了UnicodeEncodeError的錯誤,Google了一下發現這個問題不單單是在crontab中會出現,在使用管道或者重定向的時候都會出現這個問題,緣由是編碼不一樣。ip
在終端中直接執行Python程序時,Python會將輸出內容自動編碼爲終端所使用的編碼,我使用的終端編碼是utf-8,因此不會出錯,輸出的內容也是正常的。可是在使用管道或者重定向時,編碼格式爲ascii,Python會用ascii編碼格式去encode輸出的字符串,可是字符串的編碼使用的時utf-8,因此會出現UnicodeEncodeError的錯誤。utf-8
解決方法:
方法一:在程序中輸出的字符串都加上encode('utf-8')
;
方法二:在crontab中加上PYTHONIOENCODING=utf-8
,將Python的stdout/stderr/stdin
編碼設置爲utf-8。ci