Ответ 1
В Python 3 это вызвано ошибкой в стандартной библиотеке ввода-вывода Python. Ошибка была исправлена в Python 3.3.
В терминале Unix ввод Ctrl + D фактически не закрывает процесс stdin. Но ввод в Enter или Ctrl + D вызывает системный вызов OS read
для немедленного возврата. Итак:
>>> sys.stdin.read(100)
xyzzy (I press Enter here)
(I press Ctrl+D once)
'xyzzy\n'
>>>
sys.stdin.read(100)
делегируется sys.stdin.buffer.read
, который вызывает систему read() в цикле до тех пор, пока он не накапливает полный запрошенный объем данных; или система read() возвращает 0 байт; или возникает ошибка. (docs) (source)
Нажатие Enter после первой строки заставляет систему read() возвращать 6 байтов. sys.stdin.buffer.read
снова вызвал read(), чтобы попытаться получить больше ввода. Затем я нажал Ctrl + D, заставив read() вернуть 0 байт. В этот момент sys.stdin.buffer.read
сдался и вернул только 6 байтов, которые он собрал ранее.
Обратите внимание, что процесс по-прежнему имеет мой терминал на stdin, и я все еще могу напечатать материал.
>>> sys.stdin.read() (note I can still type stuff to python)
xyzzy (I press Enter)
(Press Ctrl+D again)
'xyzzy\n'
OK. Это та часть, которая была разрушена, когда этот вопрос изначально был задан. Он работает сейчас. Но до Python 3.3 произошла ошибка.
Ошибка была немного сложной - в основном проблема заключалась в том, что два отдельных слоя выполняли одну и ту же работу. BufferedReader.read()
было написано многократно называть self.raw.read()
, пока оно не вернет 0 байт. Однако необработанный метод FileIO.read()
выполнял собственный цикл - до нуля. Итак, в первый раз, когда вы нажмете Ctrl + D на Python с этой ошибкой, это приведет к тому, что FileIO.read()
вернет 6 байтов в BufferedReader.read()
, после чего немедленно вызовет self.raw.read()
снова. Второй Ctrl + D приведет к возврату 0 байтов, а затем BufferedReader.read()
, наконец, выйдет.
Это объяснение, к сожалению, намного дольше, чем мое предыдущее, но оно имеет силу быть верным. Ошибки такие...