gpt4 book ai didi

Python subprocess.Popen 管道 IO 意外阻塞

转载 作者:太空宇宙 更新时间:2023-11-04 12:07:44 32 4
gpt4 key购买 nike

我正在尝试使用 subprocess.Popen 来控制 ssh 进程并通过管道与其交互,如下所示:

p=subprocess.Popen(['ssh','-tt','LOGIN@HOSTNAME'], stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
universal_newlines=True)

while True:
(out_stdout,out_stderr)=p.communicate(timeout=10)
if out_stderr:
print(out_stderr)
if not out_stdout:
raise EOFError
print(out_stdout)

在没有 ssh 的 '-tt' 选项的情况下,这工作正常。但是,如果没有分配伪 tty,我需要在 ssh 远程端与之交互的程序就会中断,所以我不得不使用它。

这似乎是 p.communicate 读取然后无限期阻塞(或直到超时),即使输入可用也是如此。

我已经使用对 io.read、select.select 等较低级别的调用重写了它,以避免通过 Popen.communicate。 Select 实际上会将文件描述符返回为就绪状态,但对该文件描述符的后续 io.read 也会阻塞。如果我禁用“通用换行符”并在 Popen 调用中设置“bufsize=0”,则它可以正常工作,但随后我不得不自己进行二进制/Unicode 转换和行结束处理。

不过值得一提的是,在 p.communicate 版本中禁用 universal_newlines 也会无限期地阻塞,所以它不仅如此。

关于如何让行缓冲输入在这里正常工作而无需重新实现所有内容,有什么建议吗?

最佳答案

子进程和 SSH 二进制文件的替代库更适合此类任务。

parallel-ssh :

from pssh.pssh2_client import ParalellSSHClient
client = ParallelSSHClient(['HOSTNAME'], user='LOGIN')
output = client.run_command('echo', use_pty=True)

for host, host_output in output.items():
for line in host_output.stdout:
print(line)

echo 替换为您需要运行的命令,或者如果不需要命令则保持原样。这些库要求将某些内容作为命令传入,即使远程端自动执行某些内容也是如此。

另请参阅 single host SSHClient 的文档同一个项目。

根据文档,行解析和编码由同样跨平台的库处理。

还有其他的,如 paramiko 和 ssh2-python,它们的级别较低,需要更多代码来实现上面的等效项 - 请参阅它们各自的主页以获取示例。

关于Python subprocess.Popen 管道 IO 意外阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50010997/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com