我在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
连在一起?
答案 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?