В Python 3 это произошло из-за ошибки в стандартной библиотеке ввода / вывода Python .Ошибка была исправлена в Python 3.3.
В терминале Unix нажатие клавиш Ctrl + D фактически не закрывает стандартный ввод процесса.Но ввод 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 () возвращает 0 байтов;или произошла ошибка. (документы) (источник)
Нажатие клавиши Enter после первой строки заставило систему read () вернуть 6 байтов.sys.stdin.buffer.read
снова вызвал read (), чтобы попытаться получить больше информации.Затем я нажал Ctrl + D, в результате чего read () вернул 0 байтов.В этот момент sys.stdin.buffer.read
сдался и возвратил только 6 байтов, которые он собрал ранее.
Обратите внимание, что у процесса все еще есть мой терминал на stdin, и я все еще могу набирать вещи.
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()
наконец завершится.
Это объяснение, к сожалению, намного длиннее моего предыдущего, но оно имеет достоинствобыть правильным.Ошибки такие ...