En Python 3, esto se debió a a bug in Python's standard I/O library. El error fue corregido en Python 3.3.
En un terminal Unix, al presionar Ctrl + D en realidad no se cierra el estado del proceso. Pero escribir Enter o Ctrl + D hace que la llamada del sistema OS read
se devuelva de inmediato. Por lo tanto:
>>> sys.stdin.read(100)
xyzzy (I press Enter here)
(I press Ctrl+D once)
'xyzzy\n'
>>>
sys.stdin.read(100)
se delega en sys.stdin.buffer.read
, que llama al sistema read() en un bucle hasta que se acumula la cantidad solicitada completa de los datos; o el sistema read() devuelve 0 bytes; o se produce un error (docs)(source)
Al pulsar Enter después de la primera línea, el sistema read() devolvió 6 bytes. sys.stdin.buffer.read
llamado read() nuevamente para tratar de obtener más información. Luego presioné Ctrl + D, lo que hizo que read() devolviera 0 bytes. En este punto, sys.stdin.buffer.read
se dio por vencido y devolvió solo los 6 bytes que había recogido anteriormente.
Tenga en cuenta que el proceso todavía tiene mi terminal en stdin, y todavía puedo escribir cosas.
>>> sys.stdin.read() (note I can still type stuff to python)
xyzzy (I press Enter)
(Press Ctrl+D again)
'xyzzy\n'
OK. Esta es la parte que se rompió cuando se formuló esta pregunta originalmente. Ahora funciona. Pero antes de Python 3.3, había un error.
El error fue un poco complicado --- básicamente el problema era que dos capas separadas estaban haciendo el mismo trabajo. BufferedReader.read()
se escribió para llamar al self.raw.read()
repetidamente hasta que devolvió 0 bytes. Sin embargo, el método sin formato, FileIO.read()
, realizó un bucle hasta cero bytes propios.Así que la primera vez que presione Ctrl + D en un Python con este error, provocaría que FileIO.read()
devolviera 6 bytes a BufferedReader.read()
, lo que inmediatamente llamaría self.raw.read()
nuevamente. La segunda Ctrl + D causaría que para devolver 0 bytes, y luego BufferedReader.read()
finalmente saldría.
Desafortunadamente, esta explicación es mucho más larga que la anterior, pero tiene la virtud de ser correcta. Los insectos son así ...
No obtengo ese efecto en OSX. Sin embargo, si presiono directamente después de presionar 5, (sin un retorno de carro intermedio) lo hago, e incluso 'cat' hace eso. –
@Kristo: su ejemplo debe estar formateado para mostrar '' en la misma línea que '5'. Si está viendo el comportamiento que muestra su ejemplo a partir de ahora, algo está mal. –
@Alok: mi ejemplo está formateado exactamente como lo escribí. Si cambio el código para usar 'sys.stdin.readlines()', entonces el primer finaliza el programa. –