Terminating process created in a if condition in another if condition

Viewed 64

I am new to programming and working on a hobby project. I am creating a process when a certain condition is true using subprocess module in python.

Now I want to terminate the process when the other condition is true.

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")

More code So I am using the script I found on github https://github.com/Lynbarry/WiFinder and changing it to do bit more. The changes I made looks horrible and I also wrote some functions twice to understand it better.There are still few parts which I don't understand like the "UpdateHostList" function.But I will somehow try to it figure out as I do more editing in the code.

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!!!
1 Answers

Use process.kill() to terminate process. Afterwards do process.wait() to wait till it fully terminates. Example below.

I replaced your shell command with simple python's infinite-loop program. Just for the sake of working example that can be tested by all StackOverflowers.

In your case for loop is not necessary, also my shell command doesn't matter, these two modifications were done only for runnable example purpose.

Notice in second if that I used 'process' in locals() and process is not None, this check is necessary in order to have no error if process variable wasn't yet created, in this case you don't need to kill/wait anything, because there is actually nothing to be killed/waited because there is no process created yet. Also I set variable to process = None so that you never do a second kill again on already killed process.

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!')

Output:

I will Record
I will Stop
All done!
Related