![](/img/trans.png)
[英]Why do I need shell=True here in order for Python's subprocess.check_output to work?
[英]Understanding python subprocess.check_output's first argument and shell=True
我對如何正確使用Python的子進程模塊感到困惑,特別是check_output方法的第一個參數和shell
選項。 查看下面交互式提示的輸出。 我將第一個參數作為列表傳遞,並且根據是否設置了shell=True
,我得到不同的輸出。 有人可以解釋為什么這是和輸出的輸出?
>>> import subprocess
>>> subprocess.check_output(["echo", "Hello World!"])
'Hello World!\n'
>>> subprocess.check_output(["echo", "Hello World!"], shell=True)
'\n'
現在,當我將第一個參數作為簡單字符串而不是列表傳遞時,我得到了這個討厭的堆棧跟蹤。 為什么會這樣?這里發生了什么?
>>> subprocess.check_output("echo Hello World!")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 537, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1228, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
但是,當我打開shell = True時,它會完美地運行:
>>> subprocess.check_output("echo Hello World!", shell=True)
'Hello World!\n'
所以我有點困惑,當第一個arg在一個沒有shell=True
的列表中然后作為一個簡單的字符串WITH shell=True
。 我不明白shell=True
是什么以及將第一個arg作為列表與字符串傳遞之間的區別。
從Popen
的文檔:
shell參數(默認為
False
)指定是否將shell用作要執行的程序。 如果shell為True
,建議將args
作為字符串而不是序列傳遞。在Unix上,
shell=True
,shell默認為/bin/sh
。 如果args是一個字符串,則該字符串指定要通過shell執行的命令 。 這意味着字符串的格式必須與在shell提示符下鍵入時完全相同。 這包括,例如,引用或反斜杠轉義帶有空格的文件名。 如果args是一個序列,則第一個項指定命令字符串,並且任何其他項將被視為shell本身的附加參數 。 也就是說,Popen
相當於:Popen(['/bin/sh', '-c', args[0], args[1], ...])
在具有
shell=True
Windows上,COMSPEC環境變量指定默認shell。 您需要在Windows上指定shell=True
的唯一時間是您希望執行的命令是否內置到shell中(例如dir
或copy
)。 您不需要shell=True
來運行批處理文件或基於控制台的可執行文件。
在您的情況下,由於echo
是在使用shell=True
啟動時內置的shell=True
,因此如果要將參數傳遞給echo
命令,則必須將命令作為字符串寫入或傳遞將整個命令作為字符串的序列作為第一要素。 序列的其他元素作為參數傳遞給shell ,而不是傳遞給您正在調用的命令。
在某些操作系統中, echo
也是一個程序(通常是/bin/echo
)。 這解釋了為什么你的第一個例子沒有引發異常而是輸出'\\n'
而不是預期的'Hello, World!\\n'
: /bin/echo
命令是在沒有參數的情況下執行的,因為參數被“消耗”了貝殼。
調用時引發的錯誤:
subprocess.check_output("echo Hello World!")
是由於這樣的事實,因為你沒有使用shell=True
,蟒蛇正試圖執行程序echo Hello World!
即一個名為echo<space>Hello<space>World!
。 它是一個有效的程序名稱,但是你沒有帶有該名稱的程序,因此是例外。
無論何時使用shell=True
, check_output
輸入check_output
作為第一個參數,用於引用通常輸入shell的字符串中的字符串。 “在Unix上使用shell = True,shell默認為/bin/sh
。” 這為您提供了所有shell功能。 “這意味着字符串的格式必須與在shell提示符下輸入時完全一樣。” 見Popen
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.