2011-10-31 17 views
8

He escrito un script bash que está haciendo exactamente lo que yo quiero que haga, pero expulsando el siguiente error:error de direccionamiento sys.excepthook en escritura del golpe

close failed in file object destructor: sys.excepthook is missing lost sys.stderr

estoy completamente confundido sobre cómo abordar esto. Aquí está el script:

#!/bin/bash 

usage() { echo "${0##*/} inputfile outputfile"; exit 1; } 

(($#==2)) || usage 

INPUTFILE="$1" 
OUTPUTFILE="$2" 

# All that is written between between the 'cat' command and 
#+ 'EOF' will be sent to the output file. 
cat <<EOF >$OUTPUTFILE 
$(date "+Generated on %m/%d/%y at %H:%M:%S") 

DATA AUDIT: $1 

------------ 
COLUMN NAMES 
------------ 

$(csvcut -n $INPUTFILE) 

--------------------------------------- 
FIRST TEN ROWS OF FIRST FIVE COLUMNS 
--------------------------------------- 

$(csvcut -c 1,2,3,4,5 $INPUTFILE | head -n 10) 

------------ 
COLUMN STATS 
------------ 

$(csvcut $INPUTFILE | csvstat) 

---END AUDIT 
EOF 

echo "Audited!" 

Soy bastante nuevo en los scripts de shell y muy nuevo en python. Apreciaría cualquier ayuda.

+1

El error proviene del script python (¿csvcut?), No de su script bash. Sería más útil ver el código en su lugar código relevante: D –

+0

Podría ser que al csvcut no le gusta la cabeza, ya que obliga a que la salida estándar del proceso se cierre prematuramente? –

+0

@Antti, supongo que ese sería el caso, pero me preguntaba si había algo que pudiera hacer en el script que solucionara el problema, ya que ejecutar los comandos individualmente en la línea de comando no genera el error. ¿Tiene una idea de cómo se podría cambiar la cabeza para abordar un posible problema de estirado? ¿O el código de csvcut todavía sería necesario para esto? ¡Y gracias! –

Respuesta

18

Estaba viendo este error cuando salía de una secuencia de comandos de Python 2.6.2 en el comando head en bash en Ubuntu 9.04. Añadí try bloques para cerrar stdout y stderr antes de salir de la secuencia de comandos:

try: 
    sys.stdout.close() 
except: 
    pass 
try: 
    sys.stderr.close() 
except: 
    pass 

yo ya no estoy viendo el error.

+0

¿Alguna explicación de por qué esto funciona? He estado obteniendo este error en un script de cython que hace una redirección con dup/dup2 y esto parece arreglar las cosas. – Snorfalorpagus

+1

Error relevante de Python: http://bugs.python.org/issue11380 –

+1

La solución también funciona con llamadas a '.flush' en lugar de' .close'. No sé si esto significa algo sin embargo. ('close' implica' flush'). Python 2.7.8 en Ubuntu 14.04 –

1

Supongo que la secuencia de comandos csvcut de Python funciona de otra manera pero está arrojando un error cuando intenta cerrar archivos y salir.

Si, como dices, la secuencia de comandos está funcionando y suponiendo que el error 'csvcut' arroja salidas a stderr, redirigirlo a/dev/null sería una solución temporal.

cat <<EOF >$OUTPUTFILE 2>/dev/null 

Naturalmente, cualquier otro mensaje de error en su heredoc también se redirigirá allí.

+0

Incluso como una solución temporal, eso no funciona para mí. Sigue recibiendo el mismo error. –

3

hay dos pasos que debe realizar:

Paso 1:

En su csvcut guión, encontrar todos los lugares en los que se llaman sys.stdout.write(), asegúrese sys.stdout.flush() se llama después de cada write().

Paso 2:

Con el paso 1 completado ahora debería ser capaz de capturar IOError dentro de la secuencia de comandos de Python. A continuación se muestra un ejemplo sobre cómo manejar la tubería rota:

try: 
    function_with_sys_stdout_write_call() 
except IOError as e: 
    # one example is broken pipe 
    if e.strerror.lower() == 'broken pipe': 
     exit(0) 
    raise  # other real IOError 

Espero que ayude!

+0

Esta fue una solución adecuada en mi caso. Parece que todavía se estaba escribiendo una trazabilidad en stderr mientras el guión estaba cerrándose y que la descarga del stderr antes de dejarlo funcionaba. – hayavuk

Cuestiones relacionadas