2

I need to send the stdout stream of a program across a network, to the stdin of another program, running on another host.

This can be easily accomplished using ssh:

program 1 | ssh host 'program 2'

It's trivial to call this using subprocess:

subprocess.call("program 1 | ssh host 'program 2'", shell=True)

However, since I need to run many other commands on the remote host, I'm using fabric.

Sending files with fabric is easy enough, but I can't find any documentation on sending streams. I know fabric uses the paramiko ssh library, so I could use it's channel but there seems to be no documentation for accessing the channel from fabric.

4

1 回答 1

0

我最终挖掘了织物源代码 ( fabric.operations._execute) 并想出了这个:

from fabric.state import default_channel
import subprocess

def remote_pipe(local_command, remote_command, buf_size=1024):
    '''executes a local command and a remove command (with fabric), and 
    sends the local's stdout to the remote's stdin.
    based on fabric.operations._execute'''
    local_p= subprocess.Popen(local_command, shell=True, stdout=subprocess.PIPE)
    channel= default_channel() #fabric function
    channel.set_combine_stderr(True)
    channel.exec_command( remote_command )
    read_bytes= local_p.stdout.read(buf_size)
    while read_bytes:
        channel.sendall(read_bytes)
        read_bytes= local_p.stdout.read(buf_size)
    local_ret= local_p.wait()
    channel.shutdown_write()
    received= channel.recv(640*1024) #ought to be enough for everyone
    remote_ret= channel.recv_exit_status()
    if local_ret!=0 or remote_ret!=0:
        raise Exception("remote_pipe failed: "+received)
于 2013-10-26T15:29:22.960 回答