My ultimate goal is to let my python script launch a child process, in another terminal, that runs independently from the parent:
When the parent process finishes, the child process should continue. It should not be killed.
The parent process should be able to either wait for the child to finish, or just continue its own stuff.
I achieved the goal with the script below. Please note that the child process I chose to launch is python3 child.py
, but it can be anything else (and doesn't have to be a python process). Also note that, in this case, I let the parent process wait for the child process by adding the .communicate()
in the end.
# Script parent.py
# ================
import subprocess, shutil
if __name__ == '__main__':
print('Launch child process')
p = subprocess.Popen(
['x-terminal-emulator', '-e', 'python3', 'child.py'],
).communicate()
print('Child process finished')
exit(0)
I then launch the parent:
$ python3 parent.py
It works great. The parent first prints 'Launch child process'
, then the child process appears in another terminal. The child does its things, then closes. After the child closes, the parent prints 'Child process finished'
. Great!
Unfortunately, The x-terminal-emulator
is only present on Debian and derivatives. My goal is to make this approach work on most Linux systems.
The most sensible approach I could find so far, would be to try out a few default 'terminal emulators' that are present on the most common Linux distros. For example:
'gnome-terminal'
'konsole'
'xterm'
'urxvt'
'rxvt'
'termit'
'terminator'
$TERMINAL
(this is a non-standard variable)
I tried with 'gnome-terminal'
to get started, but it already goes wrong:
# Script parent.py
# ================
import subprocess, shutil
if __name__ == '__main__':
print('Launch child process')
# For the 'gnome-terminal', the '-e' argument is deprecated.
# One should use the '--' argument instead.
p = subprocess.Popen(
['gnome-terminal', '--', 'python3', 'child.py'],
).communicate()
print('Child process finished')
exit(0)
The child process launches, but the parent doesn't wait for it to finish - even though I instructed it explicitely to do so by adding the .communicate()
at the end of Popen(..)
.
In other words, the parent prints 'Child process finished'
immediately, before the child has actually finished.
Question 1:
Why is this approach working for 'x-terminal-emulator'
and not for 'gnome-terminal'
? PS: I'm working on Ubuntu.
EDIT: I found the solution to this problem. One has to add the --wait
flag to tell the gnome-terminal
not to return until its child process exits.
Question 2:
How can I get this approach working on most Linux systems? If I try to launch any other terminal emulator like xterm
, konsole
, ... should I expect similar problems? I can't test right now, because I only have Ubuntu for the moment.