2012-07-31 33 views
5

bài đầu tiên vì vậy hãy loại xin vui lòng, tôi đã tìm kiếm rất nhiều xung quanh nhưng hầu hết mọi thứ tôi thấy có liên quan đến Python 2.Python3: UnicodeEncodeError chỉ khi chạy từ crontab

Tôi có một kịch bản Python3 rằng xây dựng một tập tin zip từ danh sách tệp; nó không thành công với UnicodeEncodeError chỉ khi kịch bản được chạy từ crontab, nhưng nó hoạt động hoàn hảo khi chạy từ bảng điều khiển tương tác. Tôi đoán có phải là một cái gì đó trong môi trường nhưng tôi chỉ có thể không có vẻ để tìm ra những gì.

Đây là trích đoạn mã:

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)) 

Và đây là dữ liệu ghi nhận cho đoạn mã này:

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 

Đây là dòng crontab:

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

Và đây là nội dung của runbackup.sh:

#! /bin/bash -l 

cd /home/vte/vtebackup/vte41/scripts 

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

Các tập tin mà trên đó các ngoại lệ xảy ra luôn luôn là như nhau, nhưng nó dường như không bao gồm bất kỳ ký tự ascii phi:

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

OS là Linux Ubuntu LTS 10,04, Python phiên bản 3.2 (được cài đặt bên bên cạnh là cài đặt với các phiên bản Python khác). Tất cả Python file nguồn có công việc này

#!/usr/bin/env python3.2 

dòng như đầu tiên

bạn có thể giúp tôi tìm thấy những gì là sai và làm thế nào để khắc phục vấn đề này?

+0

Đối với một lý do không rõ khi zipfile cố gắng để mã hóa tên tập tin để nhúng thông tin trong nó, tên tập tin có một [unicode thay thế] (http://www.htmlescape.net/dc/unicode_char_dcc3 .html). Có thể một vấn đề hệ điều hành? Bạn có thể đăng nhập 'curfile' trong tập lệnh của mình không? – CharlesB

Trả lời

11

Một thành viên trong nhóm tìm thấy độ phân giải theo số Python bug thread.

Vấn đề này đã được cố định bằng cách thêm vào trước một chỉ thị LANG cho lệnh kịch bản:

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

Tôi hy vọng điều này rất hữu ích cho những người khác bởi vì tôi có bản thân mình gãi đầu của tôi trong một thời gian về vấn đề này :)

+0

Rất tốt, cảm ơn bạn đã chia sẻ – CharlesB

+0

Cảm ơn vì điều này đã cứu mạng tôi. – akai

4

Kiểm tra ngôn ngữ của bạn. Trên bảng điều khiển tương tác, hãy chạy lệnh locale. Dưới đây là những gì tôi nhận được:

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 xác định làm thế nào để giải thích tên tập tin dựa trên một trong hai biến LC_CTYPE hoặc LANG môi trường, và tôi rất nghi ngờ rằng một trong những được đặt thành một mã hóa khác nhau trong môi trường cron của bạn.

Nếu trường hợp đó xảy ra, tên tệp của bạn sẽ được giải mã thành unicode bằng cách sử dụng mã hóa khác, tên tệp sẽ dẫn đến tên tệp không được mã hóa thành UTF-8 hoặc ASCII.

Đơn giản chỉ cần đặt biến LC_CTYPE trong định nghĩa cron của bạn, hoặc trên một dòng trên nó sở hữu trước sự xâm nhập thời gian, hoặc như là một phần của lệnh để thực hiện:

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

Như thường lệ với các vấn đề trăn Unicode, các câu trả lời nằm trong số Unicode HOWTO, section on filenames.

1

cho Trung Quốc

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 "' hoạt động tốt 4 tôi – Jim

Các vấn đề liên quan