2012-07-31 13 views
5

primer post así que por favor clase, he buscado mucho alrededor, pero la mayoría de las cosas que encontré son relevantes para Python 2.python3: UnicodeEncodeError solamente cuando se ejecuta desde crontab

Tengo un script python3 que construye un archivo zip de una lista de archivos; falla con UnicodeEncodeError solo cuando el script se ejecuta desde crontab, pero funciona sin problemas cuando se ejecuta desde la consola interactiva. Supongo que debe haber algo en el entorno, pero parece que no puedo entender qué.

Este es el extracto de código:

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

Y esto es la salida de registro de este fragmento de código:

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 

Esta es la línea crontab:

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

Y esto es el contenido de runbackup.sh:

#! /bin/bash -l 

cd /home/vte/vtebackup/vte41/scripts 

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

El archivo en el que ocurre la excepción es siempre la misma, pero no parece incluir cualquier caracteres no ASCII:

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

sistema operativo es Linux Ubuntu LTS 10.04, Python versión 3.2 (lado instalado al lado como altinstall con otras versiones de Python). archivos de origen Todos Python tienen este tinglado

#!/usr/bin/env python3.2 

como primera línea de

¿Me puede ayudar a encontrar lo que está mal y cómo solucionar este problema?

+0

Por una razón desconocida cuando se trata archivo zip para codificar el nombre del archivo para incrustar información en ella, el nombre de archivo tiene una [suplentes de Unicode] (http://www.htmlescape.net/dc/unicode_char_dcc3 .html). Tal vez un problema de sistema operativo? ¿Puedes registrar 'curfile' en tu script? – CharlesB

Respuesta

11

Un miembro del equipo encontró la resolución en Python bug thread.

El problema se solucionó anteponiendo una directiva LANG en el comando de script:

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

Espero que esto sea útil para los demás porque me conseguí rascándome la cabeza por un tiempo en este :)

+0

Bonito encontrado, gracias por compartir – CharlesB

+0

Gracias, esto me salvó la vida. – akai

4

Verifica tu locale En la consola interactiva, ejecute el comando locale. Esto es lo que me sale:

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 determina cómo interpretar los nombres de archivo basados ​​tanto en la variable LC_CTYPE o LANG medio ambiente, y sospecho fuertemente que uno de ellos se ajusta a una codificación diferente en su entorno cron.

Si ese es el caso, sus nombres de archivo se habrán decodificado en Unicode con una codificación diferente, que luego dará como resultado nombres de archivo que no se pueden codificar a UTF-8 o ASCII.

Basta con establecer la variable LC_CTYPE en la definición de cron, ya sea en una línea por sí mismo que precede a la entrada de tiempo, o como parte de la ejecución del comando:

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

Como siempre con problemas Unicode de Python, el la respuesta se encuentra en el Unicode HOWTO, section on filenames.

1

para chino

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 "' funciona bien 4 me – Jim

Cuestiones relacionadas