Chr*_*ark 4 subprocess python-3.x 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)
Run Code Online (Sandbox Code Playgroud)
但是,这会失败:
AttributeError: 'str' object has no attribute 'fileno'
Run Code Online (Sandbox Code Playgroud)
ps2期待一个类似文件的对象,但输出ps1是一个简单的字符串。
有没有办法将命令链接在一起subprocess.run?
subprocess.run()不能ls | cowsay在没有 shell 的情况下实现,因为它不允许同时运行各个命令:每个subprocess.run()调用都会等待进程完成,这就是它返回CompletedProcess对象的原因(请注意此处的“完成”一词)。ps1.stdout在您的代码中是一个字符串,这就是为什么您必须将其作为input而不是stdin需要文件/管道的参数传递(有效.fileno())。
要么使用外壳:
subprocess.run('ls | cowsay', shell=True)
Run Code Online (Sandbox Code Playgroud)
或者使用subprocess.Popen, 来同时运行子进程:
from subprocess import Popen, PIPE
cowsay = Popen('cowsay', stdin=PIPE)
ls = Popen('ls', stdout=cowsay.stdin)
cowsay.communicate()
ls.wait()
Run Code Online (Sandbox Code Playgroud)
请参阅如何使用 subprocess.Popen 通过管道连接多个进程?
事实证明subprocess.run有一个input参数可以处理这个问题:
ps1 = subprocess.run(['ls'], universal_newlines=True, stdout=subprocess.PIPE)
ps2 = subprocess.run(['cowsay'], universal_newlines=True, input=ps1.stdout)
Run Code Online (Sandbox Code Playgroud)
另外,以下内容也有效,但不使用input:
ps1 = subprocess.run(['ls'], universal_newlines=True, stdout=subprocess.PIPE)
ps2 = subprocess.run(['cowsay', ps1.stdout], universal_newlines=True)
Run Code Online (Sandbox Code Playgroud)