簡體   English   中英

為什么我們在運行subprocess.check_output(xyz,shell = True)之后從終端丟失stdout?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM