Python子进程:使用subprocess.run链接命令

时间:2015-12-08 03:15:14

标签: python-3.x subprocess python-3.5

我在Python 3.5中尝试使用subprocess.run。为了将两个命令链接在一起,我认为以下应该可以工作:

import subprocess

ps1 = subprocess.run(['ls'], universal_newlines=True, stdout=subprocess.PIPE)
ps2 = subprocess.run(['cowsay'], stdin=ps1.stdout)

然而,这失败了:

AttributeError: 'str' object has no attribute 'fileno'

ps2期待一个类似文件的对象,但ps1的输出是一个简单的字符串。

有没有办法将命令与subprocess.run连在一起?

2 个答案:

答案 0 :(得分:3)

事实证明subprocess.run有一个input参数来处理这个问题:

ps1 = subprocess.run(['ls'], universal_newlines=True, stdout=subprocess.PIPE)
ps2 = subprocess.run(['cowsay'], universal_newlines=True, input=ps1.stdout)

此外,以下也有效,不使用input

ps1 = subprocess.run(['ls'], universal_newlines=True, stdout=subprocess.PIPE)
ps2 = subprocess.run(['cowsay', ps1.stdout], universal_newlines=True)

答案 1 :(得分:3)

subprocess.run()无法在没有shell的情况下实现ls | cowsay,因为它不允许同时运行各个命令:每个subprocess.run()调用都等待完成的过程就是它返回CompletedProcess对象的原因(注意单词"完成"那里)。您的代码中的ps1.stdout是一个字符串,这就是您必须将其作为input传递而不是需要文件/管道的stdin参数(有效.fileno())的原因。 / p>

使用shell:

subprocess.run('ls | cowsay', shell=True)

或者使用subprocess.Popen来同时运行子进程:

from subprocess import Popen, PIPE

cowsay = Popen('cowsay', stdin=PIPE)
ls = Popen('ls', stdout=cowsay.stdin)
cowsay.communicate()
ls.wait()

请参阅How do I use subprocess.Popen to connect multiple processes by pipes?