我有一项家庭作业,目的是捕获用户和AP之间通过Scapy进行的4way握手。我试图使用“ 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())
答案 0 :(得分:1)
虽然您不应该这样做(尝试依赖硬编码的延迟本质上是容易出现竞争条件的原因),但问题是由kill()
仍在启动时交付sh
引起的可以通过sleep
微小的“解决”(不可靠,但足以演示)问题来证明,该问题足够长的时间让shell启动并运行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])
答案 1 :(得分:0)
从不,并且我的意思是,从不终止进程是正常操作的一部分。不能保证在终止进程时进程进行了多长时间,因此在这种情况下,您将无法期望得到任何特定的结果。
要明确不向输入传递任何子流程,以防止在尝试读取stdin
时挂起:
根据run a process to /dev/null in python将其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
(在后台使用前者)是通过在两个单独的线程中读取stdout
和stderr
来实现的。 在常用情况下,便捷功能优于Popen
(在您的情况下为check_output
),因为它们为您解决了上述所有警告
1 管道已完全缓冲,a typical buffer size is 64KB