I am trying to make an app launcher, but it does not work, while another subprocess is working. I am launching firefox, but another tasks become completed only when the window with firefox is closed. Code:
import subprocess
while True:
app = input('>>> ')
subprocess.call(app)
Example: i start an app, and launch a web-browser, then type "atom" and "leafpad" to open them, but they become completed only when the window with browser is closed.
2 Answers 2
You could create a thread which runs the subprocess.call command.
A cheap trick would be to replace subprocess.call by subprocess.Popen
import subprocess
while True:
app = input('>>> ')
subprocess.Popen(app)
you're expected to assign the result so you can read the command output as a stream (with the proper redirection parameters that aren't by default), but it can also be used as a quick way to run stuff in background.
As soon as Popen is called and the process is launched, the python script resumes.
Caution: If you don't store the process handle, you have no further control on the application and you also don't know if the process could be launched at all. Storing the handle in a dictionary would allow your small shell internal command to kill those processes at will.
To make sure that the process was launched, it's still better to us a thread and call subprocess.call in this thread (blocking but in the thread) and check return code.
Comments
subprocess.call and subprocess.run wait until completion. If you need asynchronous processes, you need to use subprocess.Popen directly.
Example from a test case where the communication between two processes is tested:
sub_pro = Popen(tst_subscriber, stdout=subprocess.PIPE, env=test_env)
pub_pro = Popen(tst_publisher, stdout=subprocess.PIPE, env=test_env)
timeout_sub = Timer(timeout, kill_subscriber, [sub_pro])
timeout_pub = Timer(timeout, kill_publisher, [pub_pro])
timeout_sub.start()
timeout_pub.start()
(output, err) = sub_pro.communicate()