![](/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.