2015-12-08 28 views
0

我在Python 3.5中试验subprocess.run。要链接两个命令在一起,我本来以为下面应该工作:Python子进程:链接命令与子进程.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一起链接?

回答

1

原来,subprocess.runinput参数处理这个问题:

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) 
2

subprocess.run()不能用于在没有shell的情况下实现ls | cowsay,因为它不允许同时运行各个命令:每个subprocess.run()调用都会​​等待进程完成,这就是为什么它返回CompletedProcess对象(请注意“完成”一词)。您的代码中的ps1.stdout是一个字符串,因此您必须将其作为input传递给它,而不是stdin参数,该参数需要文件/管道(有效的.fileno())。

无论是使用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?

+0

感谢。我意识到了Popen语法,但是专门研究如何在Python 3.5+中通过'subprocess.run'链接命令。将'input'参数链接到'subprocess.run'确实是可能的。 –

+2

@ChrisClark:你明白这个区别:'ls | cowsay'和'output = $(ls); cowsay <<<“$ output”'? – jfs