2

I'm looking to leave a process running after terminating the original process.

The following code will not keep it's process running after killing the original.

args = ['yes']
Popen(args, shell=True, stdout=None, stdin=None, stderror=None)

I've tried everything I can think of, I've used variations of os.spawn() and could not get them to stay open.

It seems to send a keyboard interrupt to the child process(the command yes).

Chaos
  • 471
  • 4
  • 20

3 Answers3

2

The problem is that even though your subprocess doesn't have access to the console via the standard streams, it will still have a controlling terminal; a process can receive signals such as TSTP (stop, ^Z) and INT (^C) from its controlling terminal. Therefore what you want to have is to detach the process from the controlling terminal and the entire session. When you do this, you'll have a proper daemon process.

In C world and in Python 2 you can achieve this by calling setsid in the child process, which will create a new session for the child process. Additionally the new session will not have a controlling terminal.

In Python 3.2+ this is even easier - just pass in start_new_session=True to the Popen:

If start_new_session is true the setsid() system call will be made in the child process prior to the execution of the subprocess. (POSIX only)

Changed in version 3.2: start_new_session was added.

Community
  • 1
  • 1
  • Thanks Antti! This works correctly. Also note to anyone else that found this solution, If you are using PyCharm, it will automatically kill the new session on close. It works when i run it from my terminal instead. – Chaos May 28 '18 at 21:01
  • 2
    I believe PyCharm does some dark magic to track whatever processes are running under it so that it can kill them. – Antti Haapala -- Слава Україні May 28 '18 at 21:05
1

If handling the multiprocess interface seems too complex there is a application called 'screen' available on most linux distributions that you can call with a one-shot commandline and it will stay active. It is full-featured and easy to interact with.

it is called something like this.

#!/usr/bin/python
import subprocess
subprocess.call(["screen", "-S", "session_name", "-X", "stuff", "'command here'`echo -ne '\015'`"])

please remember to check out the man page for what each option does and all the features that are available.

I have used this in the past to run watchdog processes on remote servers. later you can reconnect to the session by invoking screen as follows

screen -d -r -S "session_name"

When ready to disconnect from the screen process and leave it active you issue the following key-sequence at the commandline.

Ctl-a Ctl-d

also remember the command to list all available commands

Ctl-a ?

When outside of screen if you want to see all the instances available use the command

screen -l

original reference from here

webmite
  • 575
  • 3
  • 6
-2

Try disabling the command that closes the terminal.

bob
  • 1
  • 2
    The point of this question is to be able to close the terminal. Use python to run some command, end that process and anything spawned by python stays up. – Chaos May 28 '18 at 20:42