2017-06-12 179 views
1

如何在Python中的远程服务器上执行命令并将标准输出传递给本地命令?要做到ssh host 'echo test' | cat在Python,我已经试过使用Paramiko的标准输出作为标准输入与子流程

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不能作为stdin与subprocess.Popen一起使用。

回答

1

是的,subprocess无法重定向“假”文件上的输出。它需要fileno这是只与“真实”的文件定义(io.BytesIO()也没有)。

我会做手工,如下面的代码演示:

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

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

1

根据该文档,在ChannelFile对象并不直接包装一个实际文件描述符(因为解密和多路分解等内SSH发生)的和,所以它不能直接被用作a文件描述符为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。

+1

'while proc.poll():'并不是真的必要的,它是_wrong_。如果成功完成,它将返回0.您必须执行'while proc.poll()不是None:'以主动等待程序退出。 –

相关问题