使用Paramiko的stdout作为子进程的stdin

时间:2017-06-12 15:56:58

标签: python subprocess paramiko

如何在Python中在远程服务器上执行命令并将stdout传递给本地命令?要在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的stdin。

2 个答案:

答案 0 :(得分:1)

是的,subprocess无法重定向"假冒"文件。它需要fileno,它只用" real"定义。文件(io.BytesIO()也没有)。

我会手动完成,如下面的代码所示:

proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE)
proc.stdin.write(ssh_stdout.read())
proc.stdin.close()

所以你告诉Popen输入是一个管道,然后你在管道中写入ssh输出数据(并关闭它以便cat知道什么时候必须结束)

答案 1 :(得分:1)

根据文档,define i32 @test2() { entry: %calltmp = call i32 @UInt() %datasize = alloca i32 switch i32 %calltmp, label %sw.bb.0 [ i32 1, label %sw.bb.1 i32 2, label %sw.bb.2 i32 3, label %sw.bb.3 ] ; %res = alloca i8 ===> deleted ;store i8 0, i8* %res ===> deleted ;%datasize1 = load i32, i32* %datasize ===> deleted ret i32 %datasize1 ===> UNABLE to delete sw.bb.0: ; preds = %entry %resclone0 = alloca i10 store i10 0, i10* %resclone0 %datasize1clone0 = load i32, i32* %datasize 对象不会直接包装实际的文件描述符(因为在SSH中发生解密和解复用等),所以它不能直接用作ChannelFile的文件描述符。

这样的东西
Popen

可能有用;即,您手动读取SSH标准输出流,一次最多4096个字节,并将它们写入子进程的标准输入管道。 我不确定远程命令退出时上面的代码如何表现,所以YMMV。