Use Paramiko's stdout as stdin with subprocess

风流意气都作罢 提交于 2020-01-11 11:34:32

问题


How can I execute a command on a remote server in Python and pipe the stdout to a local command? To do ssh host 'echo test' | cat in Python, I have tried

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)

but I get the exception 'ChannelFile' object has no attribute 'fileno'. It seems that Paramiko's ssh_stdout can't be used as stdin with subprocess.Popen.


回答1:


Yes, subprocess cannot redirect output on a "fake" file. It needs fileno which is defined only with "real" files (io.BytesIO() doesn't have it either).

I would do it manually like the following code demonstrates:

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

so you're telling Popen that the input is a pipe, and then you write ssh output data in the pipe (and close it so cat knows when it must end)




回答2:


According to the docs, the ChannelFile object does not directly wrap an actual file descriptor (because of the decryption and demuxing and so on that occurs within SSH), so it can't directly be used as a file descriptor for Popen.

Something like

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)

might work; i.e. you read the SSH stdout stream manually, up to 4096 bytes at a time, and write them to the subprocess's stdin pipe. I'm not sure how the code above will behave when the remote command exits, though, so YMMV.



来源:https://stackoverflow.com/questions/44503787/use-paramikos-stdout-as-stdin-with-subprocess

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!