How can I launch a new process that is NOT a child of the original process?
The typical way of doing this in Unix is to double fork. In bash, you can do this with
( sleep 30 & )
(..)
creates a child process, and &
creates a grandchild process. When the child process dies, the grandchild process is inherited by init.
If this doesn't work, then your application is not waiting for child processes.
Other things it may be waiting for include the session and open lock files:
To create a new session, Linux has a setsid
. On OS X, you might be able to do it through script
, which incidentally also creates a new session:
# Linux:setsid sleep 30# OS X:nohup script -q -c 'sleep 30' /dev/null &
To find a list of inherited file descriptors, you can use lsof -p yourpid
, which will output something like:
sleep 22479 user 0u CHR 136,32 0t0 35 /dev/pts/32sleep 22479 user 1u CHR 136,32 0t0 35 /dev/pts/32sleep 22479 user 2u CHR 136,32 0t0 35 /dev/pts/32sleep 22479 user 5w REG 252,0 0 1048806 /tmp/lockfile
In this case, in addition to the standard FDs 0, 1 and 2, you also have a fd 5 open with a lock file that the parent can be waiting for.
To close fd 5, you can use exec 5>&-
. If you think the lock file might be stdin/stdout/stderr themselves, you can use nohup
to redirect them to something else.
Another way is to abandon the child
#!/bin/bashyourprocess &disown
As far as I understand, the application replaces the normal bash shell because it is still waiting for a process to finish even if init
should have taken care of this child process.It could be that the "application" intercepts the orphan handling which is normally done by init
.
In that case, only a parallel process with some IPC can offer a solution (see my other answer)
I think it depends on how your parent process tries to detect if your child process has been finished.In my case (my parent process was gnu make), I succeed by closing stdout and stderr (slightly based on the answer of that other guy) like this:
sleep 30 >&- 2>&- &
You might also close stdin
sleep 30 <&- >&- 2>&- &
or additionally disown your child process (not for Mac)
sleep 30 <&- >&- 2>&- & disown
Currently tested only in bash on kubuntu 14.04 and Mac OSX.