为什么我要preSS Ctrl + D键两次,关闭标准输入? [英] Why do I have to press Ctrl+D twice to close stdin?
问题描述
我有以下的Python脚本读取数字并输出一个错误,如果输入的不是一个数字。
进口的FileInput
进口SYS
在线路(txt.strip()为TXT在fileinput.input()):
如果不是line.isdigit():
sys.stderr.write(错误:不是一个数字:%S \\ n%线)
如果我从标准输入输入,我不得不preSS <大骨节病>控制骨节病> + <大骨节病> D 骨节病> 两次以结束程序。为什么呢?
我只需要preSS <大骨节病>控制骨节病> + <大骨节病> D 骨节病>有一次,我本身运行的Python间preTER。
的bash $蟒蛇test.py
1
2
富
4
五
&LT;按Ctrl + D&GT;
错误:不是一个数字:富
&LT;按Ctrl + D&GT;
庆典$
在Python 3里,这是由于错误在Python的标准I / O库。该错误是固定在Python 3.3。
在UNIX终端,按Ctrl + D并不真正关闭进程的标准输入。但是,无论是打字输入或Ctrl + D确实会导致操作系统读
系统调用马上回来。所以:
&GT;&GT;&GT; sys.stdin.read(100)
XYZZY(I preSS在此处输入)
(我preSS Ctrl + D键一次)
XYZZY \\ n'
&GT;&GT;&GT;
sys.stdin.read(100)
委托给 sys.stdin.buffer.read
,它调用阅读()在一个循环中,直到它积累数据的全部要求的数额制度;或)读取系统(返回0字节;或发生错误。的(文档)的(源)
pressing输入的第一行引起的()读取系统以返回6个字节之后。 sys.stdin.buffer.read
阅读称为()再次尝试获得更多的投入。然后我pressed Ctrl + D键,导致阅读()返回0字节。在这一点上,<code> sys.stdin.buffer.read 放弃了,刚刚返回更早,它已收集到的6个字节。
请注意,该进程仍然有我的标准输入终端,我仍然可以输入的东西。
&GT;&GT;&GT; sys.stdin.read()(注意我仍然可以输入东西的python)
XYZZY(I preSS回车)
(再次preSS按Ctrl + D)
XYZZY \\ n'
确定。这是当这个问题本来是问被猛击了的部分。它的工作原理吧。但在此之前的Python 3.3,有一个错误。
该缺陷是有点复杂---基本的问题是两个不同的层,做同样的工作。 BufferedReader.read()
写调用 self.raw.read()
,直到它返回0字节。然而,原始的方法, FileIO.read()
,进行它自己的环路,直到零字节。所以你第一次preSS按Ctrl + D在Python与此bug,它会导致 FileIO.read()
6个字节返回 BufferedReader.read()
,那么它会立即打电话 self.raw.read()
一次。第二次按Ctrl + D会导致的是的返回0字节,然后 BufferedReader.read()
将最终退出。
这解释是不幸的是比我的previous一大部分时间更长,但它的优点是正确的。错误是这样的...
I have the following Python script that reads numbers and outputs an error if the input is not a number.
import fileinput
import sys
for line in (txt.strip() for txt in fileinput.input()):
if not line.isdigit():
sys.stderr.write("ERROR: not a number: %s\n" % line)
If I get the input from stdin, I have to press Ctrl + D twice to end the program. Why?
I only have to press Ctrl + D once when I run the Python interpreter by itself.
bash $ python test.py
1
2
foo
4
5
<Ctrl+D>
ERROR: not a number: foo
<Ctrl+D>
bash $
In Python 3, this was due to a bug in Python's standard I/O library. The bug was fixed in Python 3.3.
In a Unix terminal, typing Ctrl+D doesn't actually close the process's stdin. But typing either Enter or Ctrl+D does cause the OS read
system call to return right away. So:
>>> sys.stdin.read(100)
xyzzy (I press Enter here)
(I press Ctrl+D once)
'xyzzy\n'
>>>
sys.stdin.read(100)
is delegated to sys.stdin.buffer.read
, which calls the system read() in a loop until either it accumulates the full requested amount of data; or the system read() returns 0 bytes; or an error occurs. (docs) (source)
Pressing Enter after the first line caused the system read() to return 6 bytes. sys.stdin.buffer.read
called read() again to try to get more input. Then I pressed Ctrl+D, causing read() to return 0 bytes. At this point, sys.stdin.buffer.read
gave up and returned just the 6 bytes it had collected earlier.
Note that the process still has my terminal on stdin, and I can still type stuff.
>>> sys.stdin.read() (note I can still type stuff to python)
xyzzy (I press Enter)
(Press Ctrl+D again)
'xyzzy\n'
OK. This is the part that was busted when this question was originally asked. It works now. But prior to Python 3.3, there was a bug.
The bug was a little complicated --- basically the problem was that two separate layers were doing the same work. BufferedReader.read()
was written to call self.raw.read()
repeatedly until it returned 0 bytes. However, the raw method, FileIO.read()
, performed a loop-until-zero-bytes of its own. So the first time you press Ctrl+D in a Python with this bug, it would cause FileIO.read()
to return 6 bytes to BufferedReader.read()
, which would then immediately call self.raw.read()
again. The second Ctrl+D would cause that to return 0 bytes, and then BufferedReader.read()
would finally exit.
This explanation is unfortunately much longer than my previous one, but it has the virtue of being correct. Bugs are like that...
这篇关于为什么我要preSS Ctrl + D键两次,关闭标准输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!