The procedure to detach from the parent process is simple: Run the command under setsid
(so it starts in a new session), redirecting standard input, output and error to /dev/null
(or somewhere else, as appropriate), in background of a subshell. Because system()
starts a new shell, it is equivalent to such a subshell, so
system("setsid COMMAND </dev/null >/dev/null 2>/dev/null &");
does exactly what is needed. In a shell script, the equivalent is
( setsid COMMAND </dev/null >/dev/null 2>/dev/null & )
(Shell scripts need a subshell, because otherwise the COMMAND
would be under job control for the current shell. That is not important when using system()
, because it starts a new shell just for the command anyway; the shell will exit when the command exits.)
The redirections are necessary to make sure the COMMAND
has no open descriptors to the current terminal. (When the terminal closes, a TERM signal is sent to all such processes.) This means standard input, standard output, and standard error all must be redirected. The above redirections work in both Bash and POSIX shells, but might not work in ancient versions of /bin/sh
. In particular, it should work in all Linux distros.
setsid
starts a new session; the COMMAND
becoming the process group leader for its own process group. Signals can be directed to either a single process, or to all processes in a process group. Termination signals are usually sent to entire process groups (since an application may technically consist of multiple related processes). Starting a new session makes sure COMMAND
does not get killed if the process group the parent proces belongs to is killed by a process-group wide signal.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…