How do I fork a process that doesn't die when shell exits?

The most reliable method appears to be:

(setsid emacs &)

This uses ( &) to fork to background, and setsid to detach from the controlling tty.

You can put this in a shell function:

fork() { (setsid "$@" &); }

fork emacs

The possibilities are:

  • The disown builtin command:

    emacs &
    disown $!
    

    & acts as command separator, and disown will default to the most recent job, so this can be shortened to:

    emacs & disown
    
  • Double-fork():

    (emacs &)
    

    Commands inside parentheses ( ) are run in a separate shell process.

  • setsid, as suggested by Rich, might be the best choice, because it unsets the controlling TTY of the process by creating a new session:

    setsid emacs
    

    However, it is also a little unpredictable - it will only fork() to background if it is the leader of a process group (which won't happen if setsid is used in a sh script, for example; in such occassions it will merely become resistant to Ctrl-C.)


You do not mention if this is running as an X app or a console app.

If it's as a console app, of course it needs to close. You got rid of it's input/output, more technically the (pseudo) tty it was on. It's very unlikely this is what you meant, so let's assume you're talking about an X app.

nohup should work, not sure why it isn't. When the shell closes, it sends SIGHUP to all processes in its process group. nohup tells the command to ignore SIGHUP.

You can also try setsid, which disconnects the process from the process group

alias emacs='setsid emacs'

Or add disown after &


Check you shell settings. You can also try screen instead of nohup.