将 Paramiko 的标准输出用作带有子进程的标准输入
Use Paramiko's stdout as stdin with subprocess
如何在 Python 中的远程服务器上执行命令并将标准输出通过管道传输到本地命令?要在 Python 中完成 ssh host 'echo test' | cat
,我已尝试
import paramiko
import subprocess
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('host', username='user')
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('echo test')
proc = subprocess.Popen(['cat'], stdin=ssh_stdout)
outs, errs = proc.communicate()
print(outs)
但我遇到异常 'ChannelFile' object has no attribute 'fileno'
。 Paramiko 的 ssh_stdout
似乎不能用作 subprocess.Popen.
的标准输入
是的,subprocess
无法重定向 "fake" 文件的输出。它需要仅用 "real" 文件定义的 fileno
(io.BytesIO()
也没有)。
我会像下面的代码演示的那样手动完成:
proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE)
proc.stdin.write(ssh_stdout.read())
proc.stdin.close()
所以你告诉 Popen
输入是一个 管道 ,然后你在管道中写入 ssh 输出数据(并关闭它所以 cat
知道什么时候必须结束)
根据文档,ChannelFile
对象没有直接包装实际的文件描述符(因为解密和解复用等发生在 SSH 中),所以它不能直接用作Popen
.
的文件描述符
类似
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('echo test')
proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE)
while proc.poll() is not None: # (fixed)
buf = ssh_stdout.read(4096)
if not buf:
break
proc.stdin.write(buf)
可能有用;即您手动读取 SSH stdout 流,一次最多 4096 个字节,并将它们写入子进程的 stdin 管道。
不过,我不确定当远程命令退出时上面的代码将如何运行,所以 YMMV。
如何在 Python 中的远程服务器上执行命令并将标准输出通过管道传输到本地命令?要在 Python 中完成 ssh host 'echo test' | cat
,我已尝试
import paramiko
import subprocess
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('host', username='user')
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('echo test')
proc = subprocess.Popen(['cat'], stdin=ssh_stdout)
outs, errs = proc.communicate()
print(outs)
但我遇到异常 'ChannelFile' object has no attribute 'fileno'
。 Paramiko 的 ssh_stdout
似乎不能用作 subprocess.Popen.
是的,subprocess
无法重定向 "fake" 文件的输出。它需要仅用 "real" 文件定义的 fileno
(io.BytesIO()
也没有)。
我会像下面的代码演示的那样手动完成:
proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE)
proc.stdin.write(ssh_stdout.read())
proc.stdin.close()
所以你告诉 Popen
输入是一个 管道 ,然后你在管道中写入 ssh 输出数据(并关闭它所以 cat
知道什么时候必须结束)
根据文档,ChannelFile
对象没有直接包装实际的文件描述符(因为解密和解复用等发生在 SSH 中),所以它不能直接用作Popen
.
类似
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('echo test')
proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE)
while proc.poll() is not None: # (fixed)
buf = ssh_stdout.read(4096)
if not buf:
break
proc.stdin.write(buf)
可能有用;即您手动读取 SSH stdout 流,一次最多 4096 个字节,并将它们写入子进程的 stdin 管道。 不过,我不确定当远程命令退出时上面的代码将如何运行,所以 YMMV。