我需要标准输入切换到非缓冲模式在Python,这样我可以关闭它读取单个字符。 我设法得到它的工作,但现在的标准输出被打破,不知怎地,好像换行字符后,一些空格字符发出,零第一线,3第二,6第三,等等,这样的:
ASD
ASD
ASD
操作系统是Ubuntu Linux操作系统的12.04,64位版本,Python版本3.2.3是。
我怎样才能从这种现象甩掉自己?
下面是我使用的代码:
import sys
import tty
import termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
tty.setraw(sys.stdin)
for i in range(0, 10):
print("ASD")
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
看起来你只是做了一个换行符,但没有回车。 更改打印到
print("ASD", end="\r\n")
该谷歌把我带到这里的时候,我正在寻找的答案,同样的问题。 由没有回车哈莱克斯共享的线索,帮助我对真理的搜索。 我发现我的回答对克里斯的Wiki,一个帖子: https://utcc.utoronto.ca/~cks/space/blog/unix/CBreakAndRaw这导致我在这里读tty.py来源: https://开头汞柱。 python.org/cpython/file/618ea5612e83/Lib/tty.py这给我带来了这样的结论:如果我们的目标是读取单个字符代替,:
tty.setraw()
使用:
tty.setcbreak()
您遇到的问题是“生”,“熟”和“CBREAK”模式之间的差异。 这些模式是内核级终端驱动的模式,而不是你的应用程序代码的模式或标准库或任何在用户空间别的。 这是指这些老派的Unix方式。 POSIX已经取代了他们一个更细粒度的属性集,但POSIX的属性将在演唱会中模仿旧的“生”,“熟”和“CBREAK”模式的方式通常有翻转辅助功能。
在熟模式下,终端驱动器本身具有原始行编辑的功能内置。 它可以处理退格,字删除(退格基本上整个单词一次)和类似的事情。 没有什么复杂的像处理箭头键或历史或类似的东西。 很原始。 在这种模式下,直到最后的行(EOL)字符发送程序不会从终端看到的任何东西,然后你的程序得到一整行,而行结束转换为Unix的标准\n
无论什么终端实际执行。 此外,作为其中的一部分,终端驱动程序回声键入的字符回到终端,使用户可以看到他们正在输入的内容。
在“熟”模式,内核级终端驱动程序也做了一些输出翻译。 而这部分被打开\n
为\r\n
如果需要的话。
此外,在“熟”模式下的终端驱动程序处理等控制-C特殊字符(发送信号情报向控制进程组(由CPython的翻译成KeyboardInterrupt异常)),并且控制-Z(发送SIGTSTP(如SIGSTOP,但可以被捕获),以控制处理组)。
在“CBREAK”模式,行编辑不再进行。 终端驱动程序给每个字符(或短字符序列,像箭头键转义序列)立即该程序。 这些字符不显示在屏幕上,所以除非你的程序,然后将它们打印用户将看不到它们。 终端驱动程序虽然仍然处理特殊字符,如控制-C和控制-Z,尽管它不再像处理退格或擦字字符(典型控制-W)行编辑字符。 此外,一些输出处理仍在进行,让司机把一个\n
为\r\n
。
在“原始”模式中,不处理是在输入或输出来完成。 无特殊字符处理,不提示,不转换\n
为\r\n
,不应对用于控制-Z,什么都没有。 这取决于是把终端原始模式做这一切的程序。
现在,你是设置属性sys.stdin
所以你可能会认为这应该不会影响sys.stdout
。 但是,事实上,无论是你的文件描述符导致终端驱动程序完全相同的“实例”。 而且它是终端驱动程序的设置,确定发生了什么。 所以,如果你通过更改这些设置也没关系sys.stdin
, sys.stdout
,甚至sys.stderr
,所有更改相同的底层终端驱动程序实例,它们影响到所有其他人。
这,当然,是不是已被改由shell启动的程序前的文件描述符的真实。
作为一个方面说明,您可以使用stty -a
命令行上看到一个完整的读出所有这些标志的(包括控制字符导致煮熟,CBREAK模式,这信号)。