簡體   English   中英

終止子進程無標准輸出

[英]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時掛起:

  • 使用<process>.communicate()或使用subprocess.check_output()代替Popen來可靠地讀取輸出

    • 通常,由於I / O緩沖,不能保證某個進程在任何特定時刻輸出任何數據。 因此,您需要在過程完成后讀取輸出流,以確保您已掌握所有內容。
    • 同時,如果進程可以產生足夠的輸出以填充I / O緩沖區1 ,則需要同時讀取流。 否則,它將掛起,等待您讀取緩沖的數據。 如果stdoutstderr都是PIPE ,則需要並行讀取它們-即在不同的線程中。
      • communicate()check_output (在check_output使用前者)通過在兩個單獨的線程中讀取stdoutstderr來實現此目的。
  • 喜歡方便功能Popen共同使用的情況 -在你的情況, check_output -因為他們照顧所有上述警告的為您服務。


1 管道已完全緩沖, 典型的緩沖大小為64KB

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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