如何在通过管道传输 STDIN 时在 Python 中禁用 TTY 回显

问题描述

要使用带有交互式 TTY 的命令行程序,您只需要在 shell 中执行该程序(当然,该程序需要在 STDIN/STDOUT 上执行阻塞 I/O 操作)。例如:python -i

但您也可以这样做:cat - | python -i。这对于先向 STDIN 提供文件然后再提供交互式 TTY 很有用。例如:cat prelude.py - | python -i。通过这种方式,您可以在将脚本的全部内容通过管道传输到 STDIN 之后获得交互式 TTY。我知道还有其他方法可以在 Python 交互式 shell 中加载脚本,这只是一个示例。

我想编写一个行为相同的 Python 脚本。这是我当前的测试脚本:

import os
import sys
import threading

def main():
    thread_loop = True
    def thread_func():
        unbuf_fd = os.fdopen(sys.stdin.fileno(),'rb',0)
        sys.stdin.close()
        sys.stdin = unbuf_fd
        unbuf_fd = os.fdopen(sys.stdout.fileno(),'wb',0)
        sys.stdout.close()
        sys.stdout = unbuf_fd
        while(thread_loop):
            sys.stdout.write(sys.stdin.read(1))
        sys.stdout.write(b'Exiting...\n')
    def signal_func(sig,frame):
        global thread_loop
        print('You pressed Ctrl+C.')
        thread_loop = False
    forward_std = threading.Thread(target=thread_func,args=())
    forward_std.start()
    forward_std.join()

if __name__ == '__main__':
    main()

python test.pycat - | python test.py 都有效,但与 python -i 不同的是,我对注入 STDIN 的内容有回声。

如何禁用此回声?以下代码适用于 python test.py

fd = sys.stdin.fileno()
fd_attr = tty.tcgetattr(fd)
tty.setcbreak(fd)

但使用 cat - | python test.py 时出现以下错误

Traceback (most recent call last):
  File "tata.py",line 33,in <module>
    main()
  File "tata.py",line 25,in main
    fd_attr = tty.tcgetattr(fd)
termios.error: (25,'Inappropriate ioctl for device')

是否有一种通用的方法可以禁用 STDIN 的回声,无论它是否通过管道传输?是否有一种特定的方法可以禁用管道标准输入的回声,并且我可以在 sys.stdin.isatty() 返回 False 时使用?

感谢您的建议!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)