0

To run a subprocess in the background without disturbing the continuity of the main code I call the Python file like this:

Popen(['secondary.py'], shell=True, stdin=None, stdout=None, stderr=None, close_fds=True)

Is there any way I can use this call to run that first file('secondary.py') and then run another file ('tertiary.py') when it finishes the process?

Something like for example:

Popen(['secondary.py','tertiary.py'], shell=True, stdin=None, stdout=None, stderr=None, close_fds=True)

Note:

I can't call one below the other like this:

Popen(['secondary.py'], shell=True, stdin=None, stdout=None, stderr=None, close_fds=True)
Popen(['tertiary.py'], shell=True, stdin=None, stdout=None, stderr=None, close_fds=True)

Because they would become two separate subprocesses, which is not my expected goal, I need to finish one and then run the other.

Digital Farmer
  • 1,705
  • 5
  • 17
  • 67
  • Keep in mind that running `secondary.py` with `shell=True` isn't a reliable way to *execute* a python file. This opens the file using the user's "default application" for python files, which might be a text editor or an IDE. Use `[sys.executable, 'secondary.py']` instead, without `shell=True`. – Aran-Fey May 17 '22 at 17:31
  • Modified, thanks for the comment! – Digital Farmer May 17 '22 at 17:35
  • In most shells, the semicolon between two commands means to run one command and then the next. Can you use `Popen('secondary.py ; tertiary.py', shell=True, ....)` – Frank Yellin May 17 '22 at 17:36
  • Hi @FrankYellin i run the attempt but this error appear ```'secondary.py ; tertiary.py' is not recognized as an internal command or external, an operable program or a batch file.``` – Digital Farmer May 17 '22 at 17:39
  • The error message suggests that you forgot the `shell=True`...? – tripleee May 17 '22 at 18:08
  • Correct @tripleee you nailed it, I had removed it to update the method indicated by Aran-Fey! – Digital Farmer May 17 '22 at 18:28

1 Answers1

2

subprocess.run waits until the command is complete. You could create a background thread that runs all the commands you want in a row.

import threading
import subprocess

def run_background():
    subprocess.run(['secondary.py'], shell=True, stdin=None, stdout=None, stderr=None, close_fds=True)
    subprocess.run(['tertiary.py'], shell=True, stdin=None, stdout=None, stderr=None, close_fds=True)

bg_thread = threading.Thread(target=run_background)
bg_thread.start()

Because this was not marked as a daemon thread, the main thread will wait until this thread has completed while exiting the program.

tdelaney
  • 73,364
  • 6
  • 83
  • 116
  • Hi @tdelaney this error appears ```assert group is None, "group argument must be None for now" AssertionError: group argument must be None for now``` as I have no knowledge with Threading, could you add the reason why this happened? – Digital Farmer May 17 '22 at 17:46
  • 1
    oops, rookie mistake on my part. `Threading.thread` has a required but not used positional argument. Its annoyed programmers for decades now. – tdelaney May 17 '22 at 18:02
  • 1
    `shell=True` seems unnecessary here, as highlighted in comments on the question. – tripleee May 17 '22 at 18:06
  • @tripleee - Yes, unneeded in this example. I assume that something else shell-like is going on in the real code. – tdelaney May 17 '22 at 19:46