没有来自被杀死的子进程的stdout

问题描述 投票:-1回答:2

我有一个家庭作业,使用scapy捕获客户端和AP之间的4路握手。即时尝试使用“aircrack-ng capture.pcap”检查我使用scapy创建的捕获文件中的有效握手

我使用Popen启动程序。程序等待用户输入所以我必须杀死它。当我在杀死它后尝试获取stdout时输出为空。

我已经尝试过stdout.read(),我尝试过沟通,我尝试过阅读stderr,并且我已经尝试过有壳和不带壳

check=Popen("aircrack-ng capture.pcap",shell=True,stdin=PIPE,stdout=PIPE,stderr=PIPE)
check.kill()    
print(check.stdout.read())
python subprocess stdout scapy kill
2个回答
1
投票

虽然你不应该这样做(试图依靠硬编码延迟本质上是竞争条件),问题是由你的kill()交付而sh仍然启动可以通过“解决”的问题证明(不可靠,但足以示范)微小的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()来实现类似的效果,从而qazxs立即打开stdin管道:

close()

0
投票

从来没有,我的意思是,永远不会将过程视为正常操作的一部分。在你杀死它的时候,无法保证它到底有多远,所以在这种情况下你不能指望它有任何特定的结果。

  • 要显式地将任何内容传递给子进程作为输入,以防止在尝试读取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将其stdin连接到/dev/null(Windows中的nul): run a process to /dev/null in python 或者使用没有参数的p=Popen(<...>, stdin=open(os.devnull)) #or stdin=subprocess.DEVNULL in Python 3.3+ stdin=PIPE - 这将传递一个空流
  • 使用<process>.communicate(),或使用<process>.communicate()而不是subprocess.check_output()来可靠地读取输出 在一般情况下,由于I / O缓冲,不保证在任何特定时刻输出任何数据。因此,您需要在流程完成后读取输出流,以确保您拥有所有内容。 同时,如果进程可以产生足够的输出来填充I / O缓冲区1,则需要在此期间继续读取流。否则,它将等待您读取缓冲数据。如果Popenstdout都是stderrs,你需要同时读取它们 - 即在不同的线程中。 PIPEcommunicate()(使用前者在引擎盖下)通过在两个单独的线程中读取check_outputstdout来实现这一点。
  • 更喜欢stderr的便利功能用于常见用例 - 在您的情况下,Popen - 因为他们为您处理所有上述警告。

1管完全缓冲和check_output

© www.soinside.com 2019 - 2024. All rights reserved.