How to run & stop python script from another python script?

Viewed 1583

I want code like this:

if True:
    run('ABC.PY')
else:
    if ScriptRunning('ABC.PY):
       stop('ABC.PY')
    run('ABC.PY'):

Basically, I want to run a file, let's say abc.py, and based on some conditions. I want to stop it, and run it again from another python script. Is it possible?

I am using Windows.

3 Answers

You can use python Popen objects for running processes in a child process

So run('ABC.PY') would be p = Popen("python 'ABC.PY'")

if ScriptRunning('ABC.PY) would be if p.poll() == None

stop('ABC.PY') would be p.kill()

This is a very basic example for what you are trying to achieve

Please checkout subprocess.Popen docs to fine tune your logic for running the script

import subprocess
import shlex
import time


def run(script):
    scriptArgs = shlex.split(script)
    commandArgs = ["python"]
    commandArgs.extend(scriptArgs)
    procHandle = subprocess.Popen(commandArgs, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    return procHandle


def isScriptRunning(procHandle):
    return procHandle.poll() is None


def stopScript(procHandle):
    procHandle.terminate()
    time.sleep(5)
    # Forcefully terminate the script
    if isScriptRunning(procHandle):
        procHandle.kill()


def getOutput(procHandle):
    # stderr will be redirected to stdout due "stderr=subprocess.STDOUT" argument in Popen call
    stdout, _ = procHandle.communicate()
    returncode = procHandle.returncode
    return returncode, stdout

def main():
    procHandle = run("main.py --arg 123")
    time.sleep(5)
    isScriptRunning(procHandle)
    stopScript(procHandle)
    print getOutput(procHandle)


if __name__ == "__main__":
    main()

One thing that you should be aware about is stdout=subprocess.PIPE. If your python script has a very large output, the pipes may overflow causing your script to block until .communicate is called over the handle. To avoid this, pass a file handle to stdout, like this

fileHandle = open("main_output.txt", "w")
subprocess.Popen(..., stdout=fileHandle)

In this way, the output of the python process will be dumped into the file.(You will have to modily the getOutput() function too for this)

import subprocess

process = None

def run_or_rerun(flag):
    global process
    if flag:
        assert(process is None)
        process = subprocess.Popen(['python', 'ABC.PY'])
        process.wait() # must wait or caller will hang
    else:
        if process.poll() is None: # it is still running
            process.terminate() # terminate process
        process = subprocess.Popen(['python', 'ABC.PY']) # rerun
        process.wait() # must wait or caller will hang
Related