如何在后台运行tsark命令,并使用python中的子进程退出它



我想在telnet上连接到远程主机设备时,使用Wireshark的命令行风格tshark进行数据包捕获。我想调用我为捕获而编写的函数:

def wire_cap(ip1,ip2,op_fold,file_name,duration):  # invoke tshark to capture traffic during session
if duration == 0:
cmd='"tshark" -i 1 -P -w '+ op_fold+file_name+'.pcap src ' + str(ip1) + ' or src '+ str(ip2)
else:
cmd='"tshark" -i 1 -a duration:'+str(duration)+' -P -w '+ op_fold+file_name+'.pcap src ' + str(ip1) + ' or src '+ str(ip2)
p = subprocess.Popen(cmd, shell=True,stderr=subprocess.PIPE)
while True:
out = p.stderr.read(1)
if out == '' and p.poll() != None:
break
if out != '':
sys.stdout.write(out)
sys.stdout.flush()

出于调试目的,我想在后台运行这个函数,根据需要调用它,并在捕获后停止它。类似于:

Start a thread or a background process called wire_capture
//Do something here
Stop the thread or the background process wire_capture

通过阅读,我意识到thread.start_new_thread()threading.Thread()似乎只有在我知道捕获的持续时间(退出条件(时才合适。我尝试使用thread.exit(),但它的行为与sys.exit()类似,并完全停止了程序的执行。我还尝试了threading.Event(),如下所示:

if cap_flg:
print "Starting a packet capture thread...."
th_capture = threading.Thread(target=wire_cap, name='Thread_Packet_Capture', args=(IP1, IP2, output, 'wire_capture', 0, ))
th_capture.setDaemon(True)
th_capture.start()
.
.
.
.
.
if cap_flg:
thread_kill = threading.Event()
print "Exiting the packet capture thread...."
thread_kill.set()
th_capture.join()

我想知道当我想停止进程时,如何让它停止(比如可以添加一个退出条件,这样我就可以退出线程执行(。我尝试的上述代码似乎不起作用。

threading.Event()方法是正确的,但您需要事件在两个线程中都可见,因此您需要在启动第二个线程并将其传入之前创建它:

if cap_flg:
print "Starting a packet capture thread...."
thread_kill = threading.Event()
th_capture = threading.Thread(target=wire_cap, name='Thread_Packet_Capture', args=(IP1, IP2, output, 'wire_capture', 0, thread_kill))
th_capture.setDaemon(True)
th_capture.start()

while循环中,让监视线程在每次迭代时检查事件,如果设置了该循环,则停止该循环(也可能终止它启动的tshark(。您还需要确保进程不会永远等待进程的输出,并忽略终止事件,只在有数据可用的情况下从管道中读取:

def wire_cap(ip1,ip2,op_fold,file_name,duration,event):  # invoke tshark to capture traffic during session
if duration == 0:
cmd='"tshark" -i 1 -P -w '+ op_fold+file_name+'.pcap src ' + str(ip1) + ' or src '+ str(ip2)
else:
cmd='"tshark" -i 1 -a duration:'+str(duration)+' -P -w '+ op_fold+file_name+'.pcap src ' + str(ip1) + ' or src '+ str(ip2)
p = subprocess.Popen(cmd, shell=True,stderr=subprocess.PIPE)
while not event.is_set():
# Make sure to not block forever waiting for 
# the process to say things, so we can see if
# the event gets set. Only read if data is available.
if len(select.select([p.stderr], [], [], 0.1)) > 0:
out = p.stderr.read(1)
if out == '' and p.poll() != None:
break
if out != '':
sys.stdout.write(out)
sys.stdout.flush()
p.kill()

然后要真正告诉线程停止,只需设置事件:

if cap_flg:
print "Exiting the packet capture thread...."
thread_kill.set()
th_capture.join()

最新更新