Python如何终止在一个if条件内创建、另一if条件触发的subprocess进程
解决方案
报错根因
process为seek()函数内的局部变量,仅在触发新建进程逻辑时才会被定义,触发终止逻辑时该变量大概率未定义,直接调用方法会抛出NameError- 未做进程状态校验:进程可能已经退出、或从未启动过,直接调用
kill()/terminate()会抛出异常 - 代码存在拼写错误:
new_lenght应为new_length,可能额外导致逻辑判断异常
修复步骤
- 新增全局变量存储
tcpdump进程实例,初始值设为None - 启动进程前判断是否已有运行中的进程,避免重复启动
- 终止进程前校验进程状态,仅当进程处于运行状态时执行终止操作
- 无需重复调用
kill()和terminate(),二者选其一即可
修改后的完整代码
import netifaces import netaddr import nmap import re import sys import time import subprocess import os hostList = [] gracePeriod = 1 process = None # 全局存储tcpdump进程实例 try: nm = nmap.PortScanner() # instance of nmap.PortScanner except nmap.PortScannerError: print('Nmap not found', sys.exc_info()[0]) sys.exit(0) except: print("Unexpected error:", sys.exc_info()[0]) sys.exit(0) def seek(): curHosts =[] global wlan_iface, process ifaces=netifaces.interfaces() #Get all the avalialbe interfaces pattern = '^w' #Pattern maching for wlan interface for position in range(len(ifaces)): name = ifaces[position] match_result = re.match(pattern,str(name)) if match_result: wlan_iface=name addrs = netifaces.ifaddresses(wlan_iface) ipinfo = addrs[netifaces.AF_INET][0] address = ipinfo['addr'] wlan_iface1=str(wlan_iface) netmask = ipinfo['netmask'] # Create ip object and get CIDR cidr = netaddr.IPNetwork('%s/%s' % (address, netmask)) a=str(cidr) nm.scan(hosts = a, arguments = '-sn -T4') # executes a ping scan localtime = time.asctime(time.localtime(time.time())) print('============ {0} ============\n'.format(localtime)) for host in nm.all_hosts(): curHosts.append((host,gracePeriod)) curHosts.remove((str(address),gracePeriod)) old=sniff_old() old_length=len(old) updateHostList(curHosts) new=sniff_new() new_length=len(new) # 修正拼写错误 if new_length>old_length: print("I will Record") # 仅当无运行中进程时才启动新进程 if process is None or process.poll() is not None: process = subprocess.Popen(['sudo', 'tcpdump', '-l', '-i', wlan_iface1, '-w', f'{new[-1]}.pcap'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) if new_length < old_length: print("I will Stop") # 仅当进程处于运行状态时才终止 if process is not None and process.poll() is None: process.kill() process.wait() process = None # 重置状态 return len(hostList) def sniff_new(): sniff_list=[] for host in hostList: sniff_list.append(host[0]) print(f"{sniff_list} NEW") return((sniff_list)) def sniff_old(): sniff_list=[] for host in hostList: sniff_list.append(host[0]) old_sniff=(sniff_list) print(f"{old_sniff} OLD") return((old_sniff)) def updateHostList(curHosts): global hostList if hostList == []: hostList = curHosts else: hostList = [(x[0],x[1]-1) for x in hostList] # only the hosts that were new in this iteration newList = [(x[0],x[1]) for x in curHosts if not (any(x[0]==y[0] for y in hostList))] for host in newList: hostList.append(host) for host in hostList: if any(host[0] == y[0] for y in curHosts): hostList[hostList.index(host)] = (host[0],gracePeriod) for host in hostList: if host[1] <= 0: hostList.remove(host) def beep(): # no sound dependency print('\a') if __name__ == '__main__': old_count = new_count = seek() startCounter = gracePeriod # are there any new hosts? while True: startCounter -= 1 time.sleep(1) # increase to slow down the speed old_count = new_count new_count = seek()
内容的提问来源于stack exchange,提问作者jay soni
相关产品推荐
相关产品推荐

