Python piping output between two subprocesses

2019-02-06 19:24发布

问题:

I'm working on some code that will DD a block device over SSH, and I'm wanting to do this with subprocess so that I can monitor the status of DD during the transfer (killing the dd process with SIGUSR1 to get its current state, and reading that using selects).

The command that I'm trying to implement would be something like this:

dd if=/dev/sda | ssh root@example.com 'dd of=/dev/sda'

The current method I tried was:

dd_process = subprocess.Popen(['dd','if=/dev/sda'],0,None,None,subprocess.PIPE, subprocess.PIPE)  
ssh_process = subprocess.Popen(['ssh','root@example.com','dd of=/dev/sda'],0,None,dd_process.stdout)

However when I run this, the SSH process becomes defunct after 10-40 seconds.
Am I being completely obtuse here, or is there no way to pipe between subprocesses like this?

Edit: Turns out my real code didn't have the hostname in it. This is the correct way to do things.

回答1:

from subprocess import Popen, PIPE
dd_process = Popen(['dd', 'if=/dev/sda'], stdout=PIPE)
ssh_process = Popen(['ssh', 'root@example.com', 'dd','of=/dev/sda'],stdin=dd_process.stdout, stdout=PIPE)
dd_process.stdout.close() # enable write error in dd if ssh dies
out, err = ssh_process.communicate()

This is way to PIPE the first process output to the second. (notice stdin in the ssh_process)



回答2:

The sh Python library makes it easy to call OS commands and pipe them.

From the documentation:

for line in tr(tail("-f", "test.log", _piped=True), "[:upper:]", "[:lower:]", _iter=True):
    print(line)