2009-12-12 25 views
5

Estoy escribiendo en mi proceso de Python desde la línea de comandos en Unix. Quiero enviar EOF (o de alguna manera limpiar el buffer stdin, así que Python puede leer mi entrada.)¿Cómo enviar EOF a Python sys.stdin desde la línea de comandos? CTRL-D no funciona

Si presiono CTRL-C, obtengo un error de teclado.

Si presiono CTRL-D, el programa simplemente se detiene.

¿Cómo descargo el buffer stdin?

+2

La manera en que funcionan la mayoría de los terminales, tan pronto como presiona Enter, su entrada se envía a Python. –

+0

Si quieres cambiar la forma en que funciona, Python tiene que cambiar la configuración del terminal, que es magia negra ... ¿ves el módulo 'termios' quizás? http://docs.python.org/library/termios.html –

Respuesta

1

Si usa 'for l in sys.stdin', se almacena en el búfer.

Se puede utilizar:

while 1: 
    l = sys.stdin.readline() 
+0

Está almacenado de todos modos. No hay diferencia entre los dos. –

+0

En realidad, lo anterior funcionó para mí. Creo que he leído en la lista de correo que 'for l in sys.stdin' tiene un búfer interno adicional, mientras que sys.stdin.readline() no. –

+2

@JasonOrendorff: en realidad hay una diferencia en Python 2 debido a [error de búfer de lectura anticipada] (http://bugs.python.org/issue3907). Podría usar 'for line in iter (sys.stdin.readline, ''):' para solucionarlo. Intenta ejecutar 'cat | python2 -u -c "" 'y escribe alguna entrada. La variante 'readline()' lleva a que las líneas estén disponibles inmediatamente. – jfs

11

Control-D no debe hacer que su programa "sólo se detienen" - debe cerrar la entrada estándar, y si sus ofertas de programas con que correctamente, puede perfectamente continuar si ¡Necesita hacerlo!

Por ejemplo, dada la siguiente st.py:

import sys 

def main(): 
    inwas = [] 
    for line in sys.stdin: 
    inwas.append(line) 
    print "%d lines" % len(inwas), 
    print "initials:", ''.join(x[0] for x in inwas) 

if __name__ == '__main__': 
    main() 

podríamos ver algo como

$ python st.py 
nel mezzo del cammin di nostra vita 
mi ritrovai per una selva oscura 
che la diritta via era smarrita 
3 lines initials: nmc 
$ 

si el control-D se dio justo después de que la introduzca en la tercera línea - el programa se da cuenta de que la entrada estándar está hecha y realiza el postprocesamiento necesario, todo ordenado y adecuado.

Si su programa sale prematuramente del control-D, debe estar mal codificado. ¿Qué hay de la edición de su pregunta para agregar el programa más "malo" que pueda concebir, para que podamos mostrarle exactamente cómo va? ¿incorrecto?

2

Creo que sé lo que está pasando. Estás golpeando ctrl-D sin tocar enter. Si desea enviar una línea al programa, simplemente presione enter. Si tocas ctrl-D sin tocar enter, puedes presionar ctrl-D nuevamente y tu programa debería ver la línea. En este caso (dos ctrl-D s en sucesión), su programa no verá una nueva línea al final de la línea.

Por ejemplo, digamos que tengo un script Python a.py:

import sys 

for line in sys.stdin: 
    sys.stdout.write('%s' % line) 

Y ejecutarlo:

$ python a.py 

Y a continuación, introduzca la siguiente:

line 1 
line 2<ctrl-D><ctrl-D> 

el programa se imprimirá:

line 1 
line 2$ 

$ es el intérprete de comandos. Aquí hay una sesión completa con la entrada anterior:

$ python a.py
línea 1
línea 2 línea 1
línea 2 $

(Negrita muestran salida. Romano caso de que el programa es para mostrar lo que he escrito, sans los dos ctrl-D s)

Si esto no es lo que sucede, debe decirnos más sobre lo que está haciendo.

1
try: 
    # You might be inside the while-loop 
    foo = raw_input('Spam: ') # Or whatever... 
except EOFError: 
    print 'And now for something completely different.' 
    sys.exit() 
Cuestiones relacionadas