118 votes

IOError : [Errno 32] Broken pipe when piping : `prog.py | othercmd`

J'ai un Python 3 très simple script :

f1 = open('a.txt', 'r')
print(f1.readlines())
f2 = open('b.txt', 'r')
print(f2.readlines())
f3 = open('c.txt', 'r')
print(f3.readlines())
f4 = open('d.txt', 'r')
print(f4.readlines())
f1.close()
f2.close()
f3.close()
f4.close()

Mais ça dit toujours :

IOError: [Errno 32] Broken pipe

J'ai vu sur Internet toutes les façons compliquées de résoudre ce problème, mais j'ai copié ce code directement, donc je pense qu'il y a quelque chose qui ne va pas avec le code et non avec le SIGPIPE de Python.

Je redirige la sortie, donc si le script ci-dessus était nommé "open.py", alors ma commande à exécuter serait :

open.py | othercommand

4voto

ssanch Points 277

Je sais que ce n'est pas la façon "correcte" de procéder, mais si vous souhaitez simplement vous débarrasser du message d'erreur, vous pouvez essayer cette solution de contournement :

python your_python_code.py 2> /dev/null | other_command

3voto

JD Baldwin Points 21

La première réponse ( if e.errno == errno.EPIPE: ) ici n'a pas vraiment fonctionné pour moi. J'ai eu :

AttributeError: 'BrokenPipeError' object has no attribute 'EPIPE'

Cependant, cela devrait fonctionner si tout ce qui vous importe est d'ignorer les tuyaux cassés sur des écritures spécifiques. Je pense que c'est plus sûr que de piéger SIGPIPE :

try:
    # writing, flushing, whatever goes here
except BrokenPipeError:
    exit( 0 )

Il est évident que vous devez décider si votre code est vraiment, vraiment terminé si vous touchez le tuyau cassé, mais dans la plupart des cas, je pense que c'est généralement vrai (n'oubliez pas de fermer les poignées de fichiers, etc.).

2voto

Jayjayyy Points 573

En fonction de la cause exacte du problème, il peut être utile de définir une variable d'environnement PYTHONUNBUFFERED=1 qui force les flux stdout et stderr à être non tamponnés. Voir : https://docs.python.org/3/using/cmdline.html#cmdoption-u

Donc, votre commande

open.py | othercommand

devient :

PYTHONUNBUFFERED=1 open.py | othercommand

Exemple :

$ python3 -m http.server | tee -a access.log
^CException ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe

$ PYTHONUNBUFFERED=1 python3 -m http.server | tee -a access.log
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
^C
$

1voto

lkreinitz Points 6

Cela peut également se produire si la fin de la lecture de la sortie de votre script meurt prématurément.

ie open.py | autreCommande

si otherCommand sort et que open.py essaie d'écrire sur stdout

J'ai eu un mauvais gawk script qui m'a fait ce joli coup.

-3voto

Paul Points 7

Les fermetures doivent être effectuées dans l'ordre inverse des ouvertures.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X