4

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.

10
  • 1
    what python version you use? Commented Oct 26, 2019 at 12:26
  • 1
    3.7, and 2.7 , if you want, I can change versions. Commented Oct 26, 2019 at 12:29
  • 1
    Also, I have few scripts in Python 2.7 and few in Python 3.6. If I can make a single script to run both, that will be great. But I can also create two separate scripts for running Python 3.7 and 2.7 code. Commented Oct 26, 2019 at 12:30
  • 1
    If you know a solution, please tell me that. Don't worry about versions, I can manage it. Commented Oct 26, 2019 at 12:32
  • 1
    I forgot to tell you, I am using Windows. Commented Oct 26, 2019 at 12:37

3 Answers 3

5

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

Sign up to request clarification or add additional context in comments.

5 Comments

Input to Popen is an array. It would either be Popen(["python", "ABC.PY'"]) or Popen(["python ABC.PY"], shell=True)
Works perfectly, Just one addition. If I call two or more script, the output of all scripts gets printed in the same command prompt. Can we open a separate command prompt for each and every script, we run?
I think this will work. Popen("python ABC.PY", creationflags=CREATE_NEW_CONSOLE)
Any disadvantage of the above line?
Hey, If the main script shuts down. Is there any way to shut down all the other subprocess?
2

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)

3 Comments

Hello, ROK's answer looks much simple. Does your program have any advanage over his? like Memory management, as you mentioned.
Both are same. If your .py scripts output spew is large, just calling .Popen() will not work. You will have to redirect the output into a file, or call communicate() over the fileHandle.
Yeah, my scripts output one line per second. I will run 4 scripts at once.
1
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.