[英]No stdout from killed subprocess
我有一項家庭作業,目的是使用船長捕獲客戶端和AP之間的4way握手。 我試圖使用“ aircrack-ng capture.pcap”來檢查我使用scapy創建的捕獲文件中的有效握手
我使用Popen啟動程序。 該程序等待用戶輸入,所以我必須殺死它。 當我嘗試殺死它后獲取標准輸出時,輸出為空。
我試過stdout.read(),試過溝通,試過閱讀stderr,在沒有外殼的情況下都嘗試過
check=Popen("aircrack-ng capture.pcap",shell=True,stdin=PIPE,stdout=PIPE,stderr=PIPE)
check.kill()
print(check.stdout.read())
盡管您不應該這樣做(嘗試依賴硬編碼的延遲本來就容易出現競爭情況),但問題是由在sh
仍在啟動時傳遞的kill()
引起的,可以通過“已解決的問題來證明” ”(不夠可靠,但足以演示),只要經過一點點sleep
就可以使外殼啟動並運行echo
:
import time
from subprocess import Popen, PIPE
check=Popen("echo hello && sleep 1000", shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
time.sleep(0.01) # BAD PRACTICE: Race-condition-prone, use one of the below instead.
check.kill()
print(check.stdout.read())
也就是說,一種更好的解決方案是關閉stdin描述符,以便讀取立即返回0字節結果。 在較新版本的Python(現代3.x)上,您可以使用DEVNULL
:
import time
from subprocess import Popen, PIPE, DEVNULL
check=Popen("echo hello && read input && sleep 1000",
shell=True, stdin=DEVNULL, stdout=PIPE, stderr=PIPE)
print(check.stdout.read())
...或者,使用Python 2.x,可以通過將一個空字符串傳遞給communicate()
來實現類似的效果,從而使用close()
立即對stdin管道進行處理:
import time
from subprocess import Popen, PIPE
check=Popen("echo hello && read input && sleep 1000",
shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
print(check.communicate('')[0])
從不,而且我的意思是, 從不終止作為正常操作一部分的進程。 無法保證在您殺死它之前進行了多長時間,因此在這種情況下您無法期望它會產生任何特定的結果。
要將任何內容都不傳遞給子進程作為輸入,以防止在嘗試讀取stdin
時掛起:
按照運行python / / dev / null的過程 將其stdin
連接到/dev/null
(在Windows中為nul
):
p=Popen(<...>, stdin=open(os.devnull)) #or stdin=subprocess.DEVNULL in Python 3.3+
或使用不帶參數的stdin=PIPE
和<process>.communicate()
-這將傳遞一個空流
使用<process>.communicate()
或使用subprocess.check_output()
代替Popen
來可靠地讀取輸出
stdout
和stderr
都是PIPE
,則需要並行讀取它們-即在不同的線程中。
communicate()
和check_output
(在check_output
使用前者)通過在兩個單獨的線程中讀取stdout
和stderr
來實現此目的。 喜歡方便功能Popen
共同使用的情況 -在你的情況, check_output
-因為他們照顧所有上述警告的為您服務。
1 管道已完全緩沖, 典型的緩沖大小為64KB
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.