读取STDOUT时终端挂起?Python标准IO异常行为原因解析
Python操作/dev/stdin和/dev/stdout的异常原因解析
操作复现
在Python交互环境中执行以下代码:
>>> writetoinput=open("/dev/stdin","w") >>> readfromoutput=open("/dev/stdout")
出现的异常现象
- 向
writetoinput写入内容后调用input(),终端不会返回写入的内容,依然等待用户手动输入 - 执行
print("hi")后尝试读取readfromoutput,终端直接挂起,必须通过键盘中断(Ctrl+C)才能恢复
原因解析
1. 写入/dev/stdin无效的原因
/dev/stdin是指向当前进程标准输入对应终端设备的符号链接(比如/dev/pts/0)。终端设备的输入缓冲区由系统终端驱动管理,只有通过终端键盘输入(或终端tty接口注入的输入)才会被放入这个缓冲区。
直接打开/dev/stdin写入数据,本质是往终端设备的输出方向写内容,这些内容只会直接显示在屏幕上,并不会进入终端的输入缓冲区。而input()是从终端输入缓冲区读取数据,所以自然无法获取到你写入的内容,仍会等待用户手动输入。
2. 读取/dev/stdout导致终端挂起的原因
/dev/stdout同样是指向终端设备的符号链接。当你执行open("/dev/stdout")时,默认使用只读模式打开终端设备,而终端设备的只读模式对应的是读取终端的输入通道(也就是等待用户键盘输入)。
此时Python交互环境本身已经在占用终端的输入通道处理用户命令,这个额外的只读打开操作会触发终端驱动进入等待输入的阻塞状态——新打开的文件对象一直在等待用户输入数据,但交互环境的输入循环也在竞争终端输入,最终导致整个终端挂起。只有发送键盘中断信号终止这个阻塞的读操作,才能恢复终端正常运行。
另外需要注意:stdout本身是进程启动时以只写模式打开的文件描述符,直接读取这个描述符对应的设备,本身就违背了它的设计用途,必然会出现异常行为。
内容的提问来源于stack exchange,提问作者The Empty String Photographer
相关产品推荐
相关产品推荐

