在另一个 if 条件中终止在 if 条件中创建的进程

Terminating process created in a if condition in another if condition

我是编程新手,从事业余项目。 我正在使用 python.

中的子流程模块在特定条件为真时创建流程

现在我想在另一个条件为真时终止进程。

if new_lenght>old_length:
       print("I will Record")
       process = subprocess.Popen(['sudo', 'tcpdump', '-l', '-i', wlan_iface1, '-w',f'{new[-1]}.pcap'], stdout=subprocess.PIPE)
if new_lenght < old_length:
       print("I will Stop")

更多代码 所以我正在使用我在 github https://github.com/Lynbarry/WiFinder 上找到的脚本并将其更改为做更多的事情。我所做的更改看起来很糟糕,我还写了两次函数来理解它 better.There 仍然有一些我不理解的部分,比如“UpdateHostList”function.But 我会以某种方式尝试将其弄清楚我在代码中做了更多编辑。

import netifaces 
import netaddr
import nmap
import re
import sys
import time
import subprocess
import os

hostList = []
gracePeriod = 1


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
   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_lenght=len(new)
   if new_lenght>old_length:
       print("I will Record")
       process = subprocess.Popen(['sudo', 'tcpdump', '-l', '-i', wlan_iface1, '-w', f'{new[-1]}.pcap'], stdout=subprocess.PIPE)
   if new_lenght < old_length:
       print("I will Stop")
       process.kill()
       process.terminate()
       process.wait()
    
   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()
        

    # DANGER!!!

使用process.kill() to terminate process. Afterwards do process.wait()等待它完全终止。示例如下。

我用简单的 python 的无限循环程序替换了您的 shell 命令。仅供所有 Whosebugers 测试的工作示例。

在你的情况下 for 循环不是必需的,我的 shell 命令也无关紧要,这两个修改仅用于可运行的示例目的。

注意第二个 if 我使用了 'process' in locals() and process is not None,如果 process 变量还没有创建,这个检查是必要的,为了没有错误,在这种情况下你不' 不需要 kill/wait 任何东西,因为实际上没有任何东西可以 killed/waited 因为还没有创建进程。另外我将变量设置为 process = None 这样你就不会再对已经被杀死的进程进行第二次杀死。

Try it online!

import subprocess
for new_lenght, old_length in [(7, 5), (3, 11)]:
    if new_lenght > old_length:
        print("I will Record")
        process = subprocess.Popen(['python', '-c', 'while True: pass'],
            stdout = subprocess.PIPE)
    if new_lenght < old_length and 'process' in locals() and process is not None:
        print("I will Stop")
        process.kill()
        process.wait()
        process = None
print('All done!')

输出:

I will Record
I will Stop
All done!