首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在后台运行tshark命令并在python中使用子进程退出该命令

如何在后台运行tshark命令并在python中使用子进程退出该命令
EN

Stack Overflow用户
提问于 2018-08-01 16:58:36
回答 1查看 1.9K关注 0票数 5

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

代码语言:javascript
复制
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()

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

代码语言:javascript
复制
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(),如下所示:

代码语言:javascript
复制
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()

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

EN

回答 1

Stack Overflow用户

发布于 2018-08-10 03:58:35

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

代码语言:javascript
复制
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 )。您还需要确保进程不会永远等待进程的输出,并忽略终止事件,只在有数据的情况下从管道读取:

代码语言:javascript
复制
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()

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

代码语言:javascript
复制
if cap_flg:
    print "Exiting the packet capture thread...."
    thread_kill.set()
    th_capture.join()
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51629214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档