[Python] script bash-pipe compatibile

Daniele Varrazzo piro a develer.com
Lun 26 Ott 2009 12:58:55 CET


On Sat, 24 Oct 2009 14:32:38 +0200, Matteo Bertini <matteo a naufraghi.net>
wrote:
> Supponiamo di voler scrivere uno script python che consuma sys.stdin e 
> scrive su sys.stdout, ad esempio:
> 
> ###
> $ cat echo.py
> import sys
> for line in sys.stdin:
>      sys.stdout.write(line)
> ###
> 
> Purtroppo l'implementazione banale non si accoppia bene con altri tools 
> tipo 'head':
> 

Curioso: problemi non dovresti averne. Ti dico un po' di motivi per cui ne
hai trovati:

1. stai usando python in maniera bufferizzata: esegui lo script usando
"python -u"

2. anche se esegui python unbuffered, file.__iter__ contiene un'altra cache
che non puoi evitare: se vuoi consumare stdin riga per riga itera
esplicitamente:

while 1:
line = sys.stdin.readline()
if not line: break
sys.stdout.write(line)

3. puoi intercettare ctrl-c, solo che l'eccezione (KeyboardInterrupt) non è
sottoclasse di Exception ma di BaseException, proprio per evitare che
ctrl-c finisca maneggiato da altri handler che non sono pensati per quello
(vedi http://docs.python.org/library/exceptions.html#exception-hierarchy).
Se esegui il tuo script con:

if __name__ == '__main__':
try:
main()
except Exception:
print >> sys.stderr, "Unexpected error"
raise
except BaseException:
pass

non dovresti avere scritture spurie in stdout quando premi ctrl-c.

Continua pure il tuo shotgun debug ;)

-- 
Daniele Varrazzo - Develer S.r.l. 
http://www.develer.com


Maggiori informazioni sulla lista Python