How can I launch a new process that is NOT a child of the original process?

bash, daemon, linux, macos

Solution

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/32
sleep   22479 user    1u   CHR 136,32      0t0       35 /dev/pts/32
sleep   22479 user    2u   CHR 136,32      0t0       35 /dev/pts/32
sleep   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.

Problem

(OSX 10.7) An application we use let us assign scripts to be called when certain activities occur within the application. I have assigned a bash script and it's being called, the problem is that what I need to do is to execute a few commands, wait 30 seconds, and then execute some more commands. If I have my bash script do a "sleep 30" the entire application freezes for that 30 seconds while waiting for my script to finish. I tried putting the 30 second wait (and the second set of commands) into a separate script and calling "./secondScript &" but the application still sits there for 30 seconds doing nothing. I assume the application is waiting for the script and all child processes to terminate. I've tried these variations for calling the second script from within the main script, they all have the same problem: - nohup ./secondScript & - ( ( ./secondScript & ) & ) - ( ./secondScript & ) - nohup script -q /dev/null secondScript & I do not have the ability to change the application and tell it to launch my script and not wait for it to complete. How can I launch a process (I would prefer the process to be in a scripting language) such that the new process is not a child of the current process? Thanks, Chris p.s. I tried the "disown" command and it didn't help either. My main script looks like this: ``` [initial commands] echo Launching second script ./secondScript & echo Looking for jobs jobs echo Sleeping for 1 second sleep 1 echo Calling disown disown echo Looking again for jobs jobs echo Main script complete ``` and what I get for output is this: ``` Launching second script Looking for jobs [1]+ Running ./secondScript & Sleeping for 1 second Calling disown Looking again for jobs Main script complete ``` and at this point the calling application sits there for 45 seconds, waiting for secondScript to finish. p.p.s If, at the top of the main script, I execute "ps" the only thing it returns is the process ID of the interactive bash session I have open in a separate terminal window. The value of $SHELL is /bin/bash If I execute "ps -p $$" it correctly tells me ``` PID TTY TIME CMD 26884 ?? 0:00.00 mainScript ``` If I execute "lsof -p $$" it gives me all kinds of results (I didn't paste all the columns here assuming they aren't relevant): ``` FD TYPE NAME cwd DIR /private/tmp/blahblahblah txt REG /bin/bash txt REG /usr/lib/dyld txt REG /private/var/db/dyld/dyld_shared_cache_x86_64 0 PIPE 1 PIPE -> 0xffff8041ea2d10 2 PIPE -> 0xffff 8017d21cb 3r DIR /private/tmp/blahblah 4r REG /Volumes/DATA/blahblah 255r REG /Volumes/DATA/blahblah ```

Original source