-2

I have a main.py which open a new cmd (subprocess) when another program (test.py, in same directory) is hanged. To determining test.py is hanged or not, I used latest modified time (os.path.getmtime(test.log)) log file, test.log (test.py is continuously writing lines to this test.log file)

Now I have few things to to:

  1. when test.py hanged open a new cmd
  2. in new opened cmd run test.py
  3. kill cmd when we opened more than 2 cmd
# test.py
import time
print("test.py started...")
time.sleep(1000) # this is so long because it is behaving like test.py is hanged
print("test.py is finished...") # before this line i want to close this terminal
# main.py
import datetime
import shelx
import subprocess
def modified_time():
    file_date = time.ctime(os.path.getmtime('test.log'))
    file_date = datetime.datetime.strptime(file_date, "%a %b %d %H:%M:%S %Y")
    delta = datetime.datetime.now() - file_date
    t = delta.total_seconds()
    return divmod(t, 60)[0]  # return minutes

cmd2 = "python test.py"
while(True):
    if modified_time() >= 2:
        b = subprocess.Popen(["start", "/wait", "cmd.exe", "/k", cmd2], shell=True)
        (output, err) = b.communicate()
        # b.wait()
        pid_lst.append(b.pid)
        print(pid_lst)
        while len(pid_lst) > 2:
            x = pid_lst.pop(0)
            #cmd_2  = f"WMIC PROCESS WHERE \"ProcessID={str(x)}\" CALL TERMINATE"
            cmd_2 = f"taskkill /PID {str(x)} /F"
            args = shlex.split(cmd_2)
            try:
                y = subprocess.Popen(args, shell=False)
                print("killed ", x)
            except Exception as e:
                print(e.args)

Veysel Olgun
  • 552
  • 1
  • 3
  • 15

1 Answers1

0

Under linux I get back the pid of the shell, and the Python processes survive.

To then get the python code to run without the shell I need to specify the full path name of the python executable:

# main.py
import datetime
import subprocess
import time
import os
import logging
import sys

def modified_time():
    file_date = time.ctime(os.path.getmtime('test.log'))
    file_date = datetime.datetime.strptime(file_date, "%a %b %d %H:%M:%S %Y")
    delta = datetime.datetime.now() - file_date
    # print(f'{file_date=}   {datetime.datetime.now()=}')
    t = delta.total_seconds()
    return  t # divmod(t, 60)[0]  # return minutes


current_dir = os.getcwd()
python_executable = sys.executable

cmd2 = f"{python_executable} test.py"

logging.basicConfig(filename='test.log', level=logging.DEBUG)
logging.error("test.log touched")

b = None

while(True):
    print(f'{modified_time()=}')
    time.sleep(.8)
    
    if modified_time() >= 2:
         
        if b is not None:
            try:
                print("killing ", b.pid)
                b.kill()
            except Exception as e:
                print(e.args)
                break
                
        b = subprocess.Popen(cmd2.split(' '), shell=False)

works with a slightly changed test.py

# test.py
import time
import logging
import os

current_dir = os.getcwd()

logging.basicConfig(filename=f'{current_dir}/test.log', level=logging.DEBUG)

logging.error("test.py started...")

time.sleep(1000) # this is so long because it is behaving like test.py is hanged

logging.info("test.py is finished...") # before this line i want to close this terminal

I also made sure the log file gets touched from the launching main.py. I didn't understand the list of pid's so I replaced it with an None initialization of b.

Both files are in the same directory. If they are in separate directories I expect some changes are needed.

Variant starting instance of test.py immediately:

# main.py
import datetime
import subprocess
import time
import os
import logging
import sys

def modified_time():
    file_date = time.ctime(os.path.getmtime('test.log'))
    file_date = datetime.datetime.strptime(file_date, "%a %b %d %H:%M:%S %Y")
    delta = datetime.datetime.now() - file_date
    # print(f'{file_date=}   {datetime.datetime.now()=}')
    t = delta.total_seconds()
    return  t # divmod(t, 60)[0]  # return minutes


current_dir = os.getcwd()
python_executable = sys.executable

cmd2 = f"{python_executable} test.py"

b = subprocess.Popen(cmd2.split(' '), shell=False)

while(True):
    print(f'{modified_time()=}')
    time.sleep(.8)
    
    if modified_time() >= 2:
        try:
            print("killing ", b.pid)
            b.kill()
        except Exception as e:
            print(e.args)
            break
                
        b = subprocess.Popen(cmd2.split(' '), shell=False)

  • Thanks @Ronald van Elburg, this kill only current running instance of subprocess, will not start a new subprocess. Is there any way where we can completely (should not show in tasklist/processList) kill the previous running and run test.py in new cmd? – OneTouchForHeight Sep 26 '22 at 03:23
  • It will start a new subprocess. Why do you think it doesn't? Do you want to have more then 1 subprocess running? In that case you should give them separate log-files and watch these individually. – Ronald van Elburg Sep 26 '22 at 06:56
  • I added a variant which starts a subprocess instance before entering the infinite loop. – Ronald van Elburg Sep 26 '22 at 07:02
  • I think I see where the confusion comes from. I am not using cmd_2 anymore, that has been replaced by b.kill(). Only cmd2 is used which starts the test.py script. – Ronald van Elburg Sep 26 '22 at 07:08