天天看點

python crontab 坑

最近用Python寫了一些資料統計的腳本,并使用crontab自動執行,但是配置crontab總是要過幾個坑才行的,這裡總結一下這次遇到的坑。

輸出

要将crontab指令的輸出記錄到日志檔案中,可以使用重定向,不僅要重定向stdout也要重定向stderr,因為Python解釋器會将異常輸出到stderr。示例:

$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執行腳本時,由于工作目錄不同,就會出現找不到檔案或者目錄不存在的問題。

解決方法是腳本中使用絕對路徑:

0 12 * * * /usr/local/bin/python /path/to/script > /var/log/file 2>&1 &           

複制

編碼

我寫的Python程式中輸出了一些中文(編碼是utf-8),在shell中直接執行沒有問題,但是crontab執行時出現了UnicodeEncodeError的錯誤,Google了一下發現這個問題不僅僅是在crontab中會出現,在使用管道或者重定向的時候都會出現這個問題,原因是編碼不同。

在終端中直接執行Python程式時,Python會将輸出内容自動編碼為終端所使用的編碼,我使用的終端編碼是utf-8,是以不會出錯,輸出的内容也是正常的。但是在使用管道或者重定向時,編碼格式為ascii,Python會用ascii編碼格式去encode輸出的字元串,但是字元串的編碼使用的時utf-8,是以會出現UnicodeEncodeError的錯誤。

解決方法:

方法一:在程式中可能輸出中文的字元串都加上encode('utf-8');
方法二:在crontab中加上PYTHONIOENCODING=utf-8,将Python的stdout/stderr/stdin編碼設定為utf-8。           

複制