更正shell=True的子进程的咒语,以获得输出而不挂起

2024-05-13 22:08:59 发布

您现在位置:Python中文网/ 问答频道 /正文

在子进程调用中,我想使用shell=True以便它在路径名上进行全局处理(下面的代码),但是this has the annoying side-effect of making ^{} spawn a child process(必须是`communicate()d/poll()ed/wait()ed/terminate()d/kill()ed/whatevah)。在

(是的,我知道globbing也可以用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)

(注:你不能告诉子进程你想要一些但不是所有的shell功能,例如全局而不是生成,这是一个严重的问题。如果有人愿意评论,我认为这是一个很有价值的PEP,比如传入一个布尔元组,或者一个二进制标志的

(PPS:you passsubprocess...(cmdstring.split() or [...])的习惯用法只是一个微不足道的习惯用法差异。我说番茄,你说番茄。在我的例子中,动机是命令是固定的,但我可能希望使用不同的filespec多次调用它。)


Tags: 代码trueoutputbin进程usrcheckshell
1条回答
网友
1楼 · 发布于 2024-05-13 22:08:59

首先,将数组传递给:

subprocess.check_output(['/usr/bin/wc','-l','A-Z*/A-Z*.F*'], shell=True)

…由于这只是在没有参数的情况下运行wc,因此在shell中还将参数-l和{}作为参数传递给shell,而不是{}。相反,您需要:

^{pr2}$

在更正之前,这将挂起,因为wc没有参数,正在从stdin读取。我建议确保stdin是在closed中传递的,而不是传递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。在

相关问题 更多 >