2012-07-31 66 views
5

的第一篇文章中運行時如此善待請,我尋覓了周圍很多,但我發現大多數事情都是相關的Python 2Python3:UnicodeEncodeError只能從crontab中

我有一個Python3腳本,建立從一個zip文件一個文件列表;只有當腳本從crontab運行時,它纔會以UnicodeEncodeError失敗,但是當它從交互式控制檯運行時,它運行得非常完美。 我想環境中一定有東西,但我似乎無法弄清楚什麼。

這是代碼摘錄:

def zipFileList(self, rootfolder, filelist, zip_file, logger): 
    count = 0 

    logger.info("Generazione file zip {0}: da {1} files".format(zip_file, len(filelist))) 
    zip = zipfile.ZipFile(zip_file, "w", compression=zipfile.ZIP_DEFLATED) 

    for curfile in filelist: 
     zip.write(os.path.join(rootfolder, curfile), curfile, zipfile.ZIP_DEFLATED) 
     count = count + 1 

    zip.close() 
    logger.info("Scrittura terminata: {0} files".format(count)) 

而這是該代碼片段的日誌輸出:

2012-07-31 09:10:03,033: root - ERROR - Traceback (most recent call last): 
    File "/usr/local/lib/python3.2/zipfile.py", line 365, in _encodeFilenameFlags 
    return self.filename.encode('ascii'), self.flag_bits 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 56-57: ordinal not in range(128) 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "XBE.py", line 45, in main 
    pam.executeList(logger) 
    File "/home/vte/vtebackup/vte41/scripts/ptActivityManager.py", line 62, in executeList 
    self.executeActivity(act, logger) 
    File "/home/vte/vtebackup/vte41/scripts/ptActivityManager.py", line 71, in executeActivity 
    self.exAct_FileBackup(act, logger) 
    File "/home/vte/vtebackup/vte41/scripts/ptActivityManager.py", line 112, in exAct_FileBackup 
    ptfs.zipFileList(srcfolder, filelist, arcfilename, logger) 
    File "/home/vte/vtebackup/vte41/scripts/ptFileManager.py", line 143, in zipFileList 
    zip.write(os.path.join(rootfolder, curfile), curfile, zipfile.ZIP_DEFLATED) 
    File "/usr/local/lib/python3.2/zipfile.py", line 1115, in write 
    self.fp.write(zinfo.FileHeader()) 
    File "/usr/local/lib/python3.2/zipfile.py", line 355, in FileHeader 
    filename, flag_bits = self._encodeFilenameFlags() 
    File "/usr/local/lib/python3.2/zipfile.py", line 367, in _encodeFilenameFlags 
    return self.filename.encode('utf-8'), self.flag_bits | 0x800 
UnicodeEncodeError: 'utf-8' codec can't encode character '\udcc3' in position 56: surrogates not allowed 

這是crontab的線:

10 9 * * * /home/vte/vtebackup/vte41/scripts/runbackup.sh >/dev/null 2>&1 

而這是runbackup.sh的內容:

#! /bin/bash -l 

cd /home/vte/vtebackup/vte41/scripts 

/usr/local/bin/python3.2 XBE.py 

爲例外情況是始終不變的,但它似乎並沒有包括任何非ASCII字符的文件:

/var/vhosts/vte41/http_docs/vtecrm41/storage/2012/July/week4/169933_Puccini_Gabriele.tif 

操作系統是Ubuntu Linux操作系統的10.04 LTS,Python版本3.2(安裝側作爲altinstall與其他Python版本一起)。 所有Python源文件有這個家當

#!/usr/bin/env python3.2 

爲第一行

你能不能幫我找到了什麼問題以及如何解決這個問題?

+0

對於當zip文件試圖編碼的文件名嵌入信息在它的一個未知的原因,文件名具有[Unicode代理](http://www.htmlescape.net/dc/unicode_char_dcc3的.html)。也許操作系統的問題?你可以在腳本中記錄'curfile'嗎? – CharlesB 2012-07-31 08:03:45

回答

11

一個團隊成員在Python bug thread中找到了該決議。

問題被固定在前面加上LANG指令的腳本命令:

* * * * * LANG=it_IT.UTF-8 /home/vte/vtebackup/vte41/scripts/runbackup.sh >/dev/null 2>&1 

我希望因爲我給自己買了抓我的頭一會兒在這個:)

+0

尼斯找到了,感謝分享 – CharlesB 2012-07-31 08:05:08

+0

謝謝你救了我的命。 – akai 2016-03-08 19:39:27

4

這是對別人有用檢查您的語言環境。在交互式控制檯上,運行命令locale。以下是我得到:

LANG= 
LC_COLLATE="en_US.UTF-8" 
LC_CTYPE="en_US.UTF-8" 
LC_MESSAGES="en_US.UTF-8" 
LC_MONETARY="en_US.UTF-8" 
LC_NUMERIC="en_US.UTF-8" 
LC_TIME="en_US.UTF-8" 
LC_ALL="en_US.UTF-8" 

Python的決定如何解釋基於要麼LC_CTYPELANG環境變量名,我強烈懷疑,其中一個被設置爲在您的cron環境不同的編碼。

如果是這樣,您的文件名將被解碼爲unicode使用不同的編碼,然後導致文件名不能編碼爲UTF-8或ASCII。

只需設置LC_CTYPE變量在你的cron的定義,掛在晾衣繩上它自己的時間條目之前,或者作爲命令的一部分來執行:

LC_CTYPE="en_US.UTF-8" 
* * * * * yourscriptcommand.py 

一如既往地與蟒蛇Unicode的問題上,答案在於Unicode HOWTO, section on filenames

1

爲中國

export LANG="zh_CN.utf-8"                    
export LC_CTYPE="zh_CN.utf-8"                   
export PYTHONIOENCODING="utf-8"                  

/export/zhangys/python3.5.2/bin/python3 diff_reporter.py > /home/admin/diff_script/cron_job.log 2>&1 
+0

'LC_ALL =「en_US.utf-8」'正常4我 – Jim 2017-08-23 06:39:56