0

I have a script "run.py" that must print "Hello", launch another script "run2.py", and then terminate (do not wait for run2.py to return). run2.py is not in the local directory and is only required to print "Hello again".

How can I do this?

# run_path = "C:/Program Files (x86)/xxx/run.py"
# run2_path = "//network_share/folder/run2.py"

**run.py**
import os

print("Hello")

# What do I do here?
# os.execl("//network_share/folder/run2.py")

exit()


**run2.py**
print("Hello again")
5
  • subprocess is a good python package that should help you to do that: docs.python.org/3/library/subprocess.html You should have a look at the Popen.communicatemethod. Commented Feb 24, 2020 at 20:45
  • @baptiste .communicate waits for the subprocess to terminate. I need run.py terminated before run2.py prints Commented Feb 24, 2020 at 21:03
  • Try using runpy module, or read the "run2.py" and use exec function Commented Feb 24, 2020 at 21:06
  • You cannot run a command after quitting the current script. Not from the script itself, at least. Commented Feb 24, 2020 at 21:21
  • @Pitto Exactly! I am trying to launch run2.py before the exiting run.py.... run.py needs to exit immediately after calling run2.py.. I will likely add a delay before the print("Hello again") to ensure run.py is closed Commented Feb 24, 2020 at 21:26

3 Answers 3

1

This seems to work for a script I have in the same folder I'm running this one in.

This should verify that the first script finishes and doesn't linger while the second script runs in its own process. It is possible on some systems, due to their configuration, the child process will terminate when the parent does. But not in this case...

I put more time into this post to add code that shows how to check if the parent process is still running. This would be a good way for the child to ensure it's exited. Also shows how to pass parameters to the child process.

# launch.py
import subprocess as sp
import os

if __name__ == '__main__':

    sp.Popen(['ps']) # Print out runniing processes.

    print("launch.py's process id is %s." % os.getpid())

    # Give child process this one's process ID in the parameters.

    sp.Popen(['python3', 'runinproc.py', str(os.getpid())])

    # ^^^ This line above anwers the main question of how to kick off a
    #     child Python script.

    print("exiting launch.py")

Other script.

# runinproc.py
import time
import subprocess as sp
import sys
import os

def is_launcher_running():
    try:
        # This only checks the status of the process. It doesn't 
        # kill it, or otherwise affect it.

        os.kill(int(sys.argv[1]), 0)

    except OSError:
        return False
    else:
        return True

if __name__ == '__main__':

    print("runinproc.py was launched by process ID %s" % sys.argv[1])

    for i in range(100):

        if is_launcher_running():
            # Is launch.py still running?
            print("[[ launch.py is still running... ]]")

        sp.Popen(['ps']) # Print out the running processes.

        print("going to sleep for 2 seconds...")

        time.sleep(2)

Bash output:

Todds-iMac:pyexperiments todd$ python3 launch.py
launch.py process id is 40975.
exiting launch.py
Todds-iMac:pyexperiments todd$ runinproc.py was launched by process ID 40975
going to sleep for 2 seconds...
  PID TTY           TIME CMD
  PID TTY           TIME CMD
40866 ttys000    0:00.09 -bash
40866 ttys000    0:00.09 -bash
40977 ttys000    0:00.04 /Library/Frameworks/Python.framework/Versions/3.8/Resources/Python.app/C
40977 ttys000    0:00.04 /Library/Frameworks/Python.framework/Versions/3.8/Resources/Python.app/C
going to sleep for 2 seconds...
  PID TTY           TIME CMD
40866 ttys000    0:00.09 -bash
40977 ttys000    0:00.04 /Library/Frameworks/Python.framework/Versions/3.8/Resources/Python.app/C
going to sleep for 2 seconds...
  PID TTY           TIME CMD
40866 ttys000    0:00.09 -bash
40977 ttys000    0:00.04 /Library/Frameworks/Python.framework/Versions/3.8/Resources/Python.app/C
going to sleep for 2 seconds...

Note that the first call to the shell, ps from launch.py is executed after launch.py exited. That's why it doesn't show up in the printed process list.

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

1 Comment

I had to change 'python3' to 'python' and it worked like a charm! Thank you so much
1

subprocess is your friend, but if you need to not wait, check out the P_NOWAIT--replacing example code in https://docs.python.org/3/library/subprocess.html

EG: pid = Popen(["/bin/mycmd", "myarg"]).pid

I don't think .communicate is what you need this time around - isn't it more for waiting?

Comments

0

The cleanest way to do this (since both scripts are written in pure Python) is to import the other script as a module and execute its content, placed within a function:

run.py

import os
import sys
sys.path.append("//network_share/folder/")

import run2 
print("Hello")

run2.main()
exit()

run2.py

def main():
    print("Hello again")

5 Comments

sys.path tells Python interpreter where to look for modules.
this method wouldn't terminate run.py before printing the contents of run2.py. I need run.py killed before "Hello again" is printed
@CodeGod I'm wondering why that is necessary. Could you give some extra sight into your problem?
what I was really trying to do was have script "run2.py" act as a updater script for "run.py". "run2.py" copies a newer version of "run.py" from a network share, replaces the local version of run.py, and then launches it. Hence why run.py needed to be killed (run2.py can't replace run.py if it's still running).
@CodeGod Then, it would be better if you executed a copy of run.py instead of itself. This unties the script for changes.

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.