![](/img/trans.png)
[英]Why do I need shell=True here in order for Python's subprocess.check_output to work?
[英]Why do we lost stdout from a terminal after running subprocess.check_output(xyz, shell=True)?
我有这个bash行:
$ printf ' Number of xml files: %s\n' `find . -name '*.xml' | wc -l`
Number of xml files: 4
$
当我以这种方式从python运行时,python 解释器停止,并且我的终端不再具有stdout ::
$ ls
input aa bb
$ python
Python 3.6.7 (default, Oct 22 2018, 11:32:17)
>>>
>>> import subprocess
>>> cmd = "printf 'xml files: %s\n' `find . -name '*.xml' | wc -l`"
>>> subprocess.check_output(['/bin/bash', cmd], shell=True)
$ ls # stdout is not seen any more I have to kill this terminal
$
显然,这里的问题不是如何从python:进行此bash工作:
>>> import subprocess
>>> cmd = "printf 'xml files: %s\n' `find . -name '*.xml' | wc -l`"
>>> out = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE)
>>> print(str(out.stdout, 'utf8'))
xml files: 4
>>>
以下两个问题来自subprocess.check_output()没有输出,以及为什么在运行python可执行文件后终端为空白? 没有回答问题
简短的版本是check_output
正在缓冲所有要返回的输出。 运行ls
,其标准输出将进入check_output
的缓冲区,而不是终端。 退出当前所在的外壳程序时,您将作为单个Python字符串一次获得所有输出。
这就引出了一个问题,为什么首先要获得一个sub shell,而不是执行cmd
的内容? 首先,您使用bash
错误; 它的参数是要运行的文件 ,而不是任意命令行。 您正在做的事情的更正确版本是
cmd = "printf 'xml files: %s\n' `find . -name '*.xml' | wc -l`"
subprocess.check_output(['/bin/bash', '-c', cmd])
或者,如果您希望subprocess
为您运行外壳程序,而不是显式执行外壳程序,
subprocess.check_output(cmd, shell=True)
将list参数与shell=True
结合起来几乎从来不是您想要的。
其次,给定您的原始代码, check_output
首先尝试将您的列表组合成一个字符串,然后将其连接到sh -c
。 也就是说,您尝试执行类似
sh -c /bin/bash "printf 'xml files: %s\n' `find . -name '*.xml' | wc -l`"
sh
运行/bin/bash
,并且您的命令字符串仅用作sh
的附加参数,出于这个问题的目的,我们可以假定它被忽略了。 因此,您处于一个交互式外壳中,其标准输出被缓冲而不是显示,如本答案的第一部分所述。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.