在子进程调用中,我想使用 shell = True ,以便它对路径名(下面的代码)进行通配,但是this has the annoying side-effect of making subprocess
spawn a child process(必须是` ()d / poll()ed / wait()ed / terminate()d / kill()ed / whatevah )。
(是的我知道可以使用fnmatch / glob完成全局操作,但是请向我展示子进程的'正确'用法,即获得stdout的最小咒语并停止子进程。)
这样可以正常工作(返回输出):
subprocess.check_output(['/usr/bin/wc','-l','[A-Z]*/[A-Z]*.F*'], shell=False)
但是这会挂起
subprocess.check_output(['/usr/bin/wc','-l','[A-Z]*/[A-Z]*.F*'], shell=True)
(PS:严重恶化的是你不能告诉你想要的子进程一些但不是所有 shell功能,例如通配但不产生。我认为这是一个值得的PEP在那里,如果有人关心评论,即传入一个布尔元组,或二进制标志的或)
(PPS:你是否通过 subprocess...(cmdstring.split() or [...])
的成语只是一个微不足道的惯用语。我说番茄,你说tomay-to。在我的情况下,动机就是命令是固定的,但我可能想用不同的文件规范多次调用它。)
答案 0 :(得分:6)
首先关闭 - 将数组传递给:
非常简单subprocess.check_output(['/usr/bin/wc','-l','A-Z*/A-Z*.F*'], shell=True)
...因为这只是在没有参数的情况下运行wc
,在shell中也传递参数-l
和A-Z*/A-Z*.F*
作为参数(对shell而不是wc
)。相反,你想要:
subprocess.check_output('/usr/bin/wc -l A-Z*/A-Z*.F*', shell=True)
在纠正之前,这会挂起,因为wc
没有参数并且正在从stdin读取。我建议确保stdin
在关闭时传递,而不是传递你的Python程序stdin
(默认行为)。
这是一种简单的方法,因为您有shell=True
:
subprocess.check_output(
'/usr/bin/wc -l A-Z*/A-Z*.F* </dev/null',
shell=True)
...交替:
p = subprocess.Popen('/usr/bin/wc -l A-Z*/A-Z*.F*', shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=None)
(output, _) = p.communicate(input='')
...这将确保Python代码中的空stdin
而不是依赖shell。