两个子进程之间的 Python 管道输出

Posted

技术标签:

【中文标题】两个子进程之间的 Python 管道输出【英文标题】:Python piping output between two subprocesses 【发布时间】:2011-06-18 07:52:32 【问题描述】:

我正在编写一些将通过 SSH DD 块设备的代码,我想用子进程执行此操作,以便我可以在传输期间监视 DD 的状态(使用 SIGUSR1 杀死 dd 进程以获取它的当前状态,并使用选择读取)。

我试图实现的命令是这样的:

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

我目前尝试的方法是:

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)

但是,当我运行它时,SSH 进程会在 10-40 秒后失效。 我在这里是完全迟钝,还是没有办法像这样在子进程之间进行管道传输?

编辑:原来我的真实代码中没有主机名。这是做事的正确方法。

【问题讨论】:

我希望您使用的是基于密钥的身份验证或其他非交互机制。 显然 ;) 我只是去掉了 ssh 参数来缩短示例 相关:How do I use subprocess.Popen to connect multiple processes by pipes? 【参考方案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()

这是将第一个进程输出通过管道传输到第二个进程的方法。 (注意 ssh_process 中的标准输入)

【讨论】:

嗯,这就是我已经拥有的,但它仍然无法正常工作。特别是当 ssh 失效时的错误是:ssh: dd of=/dev/sda: Temporary failure in name resolution @Cristian,对不起-应该是 ssh_process。 @Philip - 该错误与您的域和互联网连接(您已作为 example.com 给出)有关。可以直接完成吗?那就是不用python? 我只使用了example.com,因为我不会发布公共IP。不使用 python 时我可以完成 DD。 @Philip。我建议,使用子进程尝试一个简单的远程命令执行,比如“ls”,你有 stdout=PIPE 和 stderr=PIPE 并看到它正在工作。名称解析中的临时失败意味着当 python 尝试执行 ssh 时,域没有得到解析。【参考方案2】:

sh Python 库使调用操作系统命令和管道变得容易。

来自文档:

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

【讨论】:

sh 模块真的很棒。感谢分享。 但是使用未经检查的输入很危险

以上是关于两个子进程之间的 Python 管道输出的主要内容,如果未能解决你的问题,请参考以下文章

c - 使用管道在两个子进程之间持续通信

Python 子进程中的 ffmpeg - 无法为“管道:”找到合适的输出格式

Python、子进程、管道和选择

阻止写入标准输出

使用管道在父进程和子进程之间进行通信的问题

使用带有 python3 的子进程模块管道两个命令时遇到问题