Search code examples
python-3.xsubprocess

How to keep running a loop when calling a subprocess into it


I created a Python script which reads a txt file check.txt and depending on its content (the words 'start' or 'stop') launches or kills another python script named 'test.py'.

This is the code:

import psutil
import time
from subprocess import call
   

while True:
    with open('check.txt') as f:
        order = f.readline()

    with open('pid.txt') as f:
        pid = int(f.readline())

    if order == 'stop':
        if psutil.pid_exists(pid):
            os.kill(int(pid), 9)

    elif order == 'start':
        if not psutil.pid_exists(pid):
            print('Starting script')
            call(["C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\python.exe", "test.py"])

    print('Checking again in 10 secs...')
    time.sleep(10)

This is the test.py script:

import time
import os


pid = os.getpid()
with open("pid.txt", "w") as f:
      f.write(str(pid))    
cont = 0    
while True:
    cont += 1
    print('This script is running ' + str(cont))
    time.sleep(5)

If test.py is running already, when I write 'stop' in the text file check.txt the script works as expected killing the process and it keeps checking the txt for a new instruction.

My issue is when test.py is not running and I launch it writing the word 'start' in the text file. The script starts okay test.py but the loop does not work anymore because once entering into the subprocess call(["C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\python.exe", "test.py"]) line it never goes out from there.

Any idea how can I execute the subprocess call line and keep the loop running after it?


Solution

  • you can use subprocess.Popen instead as it is not blocking

    also you should get rid of psutil, process.returncode is None when the process is running, so you can use that instead of psutils.

    import time
    from subprocess import Popen
    
    process = None
    while True:
        with open('check.txt') as f:
            order = f.readline()
    
        if order == 'stop':
            if process is not None and process.returncode is None:
                os.kill(process.pid, 9)
    
        elif order == 'start':
            if process is None or process.returncode is not None:
                print('Starting script')
                process = Popen(["C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\python.exe", "test.py"])
    
        print('Checking again in 10 secs...')
        time.sleep(10)