2015-12-08 30 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