为了账号安全,请及时绑定邮箱和手机立即绑定

与python中子进程打开的`/dev/tty`交互

与python中子进程打开的`/dev/tty`交互

噜噜哒 2023-01-04 14:21:46
我有一个subprocess.Popen用于启动目标程序的 python 脚本:一个网络服务器。我想与目标进行交互,所以我将stdin,stdout和分配stderr给管道,现在我可以读写它们了。现在,网络服务器链接 OpenSSL 库以进行 TLS 处理。作为 TLS 处理的一部分,它会打开证书并提示输入密码。通常,在输入密码并按下回车键后,网络服务器就会开始服务。现在,您可能已经猜到了,我想从 python 脚本中输入此密码。通常,我需要做的是写入服务器的stdin. 但是,有一个问题。当 OpenSSL 提示并读取密码时,它不使用stdin/ stdout。它打开/dev/tty并使用它。结果,我必须输入密码并手动输入。下图演示了这种情况。lsof下面,您可以看到服务器输出的片段:memcached 25279 USER    0r  FIFO   0,13      0t0  7771739 pipememcached 25279 USER    1w  FIFO   0,13      0t0  7771740 pipememcached 25279 USER    2w  FIFO   0,13      0t0  7771740 pipememcached 25279 USER    3r   REG    8,1     3414  3414276 ....key.pemmemcached 25279 USER    4r   CHR    5,0      0t0       13 /dev/ttymemcached 25279 USER    5w   CHR    5,0      0t0       13 /dev/tty有没有办法拦截对/dev/tty服务器的调用,以便我可以直接从脚本写入它?
查看完整描述

1 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

通过使用 pty - 伪终端来实现您所描述的内容的标准方法。pty 看起来与普通 tty 完全一样,只是它是由软件而不是实际终端或终端仿真器控制的。

在您的情况下,您可以轻松地使用ptypython 标准库中的模块,它提供了一些使用 pty 的实用程序。具体看pty.spawn()函数:

生成一个进程,并将其控制终端连接到当前进程的标准 io. 这通常用于阻止坚持从控制终端读取的程序。预计在 pty 后面生成的进程最终将终止,并且当它确实生成时将返回。

用法示例:

import subprocess, sys


openssl_cmd = ['openssl', 'foo', 'bar']

p = subprocess.Popen([sys.executable, '-c', 'import pty, sys; pty.spawn(sys.argv[1:])', *openssl_cmd])

p.stdin.write('password\n')

print(p.wait())

在这个例子中,我们没有直接运行 openssl,而是使用 运行它spawn,这意味着无论我们写入进程的标准输入,openssl 都会从它的/dev/tty.



查看完整回答
反对 回复 2023-01-04
  • 1 回答
  • 0 关注
  • 251 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信