繁体   English   中英

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

[英]Interact with `/dev/tty` opened by subprocess in python

我有一个 python 脚本,它使用subprocess.Popen启动目标程序:网络服务器。 我想与目标交互,所以我将stdinstdoutstderr分配给管道,现在我可以读取和写入这些。

现在,网络服务器链接 OpenSSL 库以进行 TLS 处理。 作为 TLS 处理的一部分,它会打开一个证书并提示输入密码。 通常,在输入密码并按回车后,网络服务器开始提供服务。 现在,您可能已经猜到了,我想从 python 脚本中输入这个密码。 通常,我需要做的是写入服务器的stdin 但是,有一个问题。 当 OpenSSL 提示并读取密码时,它不使用stdin / stdout 它打开/dev/tty并使用它。 结果,我必须输入密码并手动输入。

下图说明了这种情况。

程序设置

下面,您可以看到服务器的lsof的 output 的片段:

memcached 25279 USER    0r  FIFO   0,13      0t0  7771739 pipe
memcached 25279 USER    1w  FIFO   0,13      0t0  7771740 pipe
memcached 25279 USER    2w  FIFO   0,13      0t0  7771740 pipe
memcached 25279 USER    3r   REG    8,1     3414  3414276 ....key.pem
memcached 25279 USER    4r   CHR    5,0      0t0       13 /dev/tty
memcached 25279 USER    5w   CHR    5,0      0t0       13 /dev/tty

有没有办法拦截服务器对/dev/tty的调用,以便我可以直接从脚本写入它?

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

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

生成一个进程,并将其控制终端与当前进程的标准 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读取。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM