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

51,876

Solution 1

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 &

Solution 2

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.)

Solution 3

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

Share:
51,876

Related videos on Youtube

sligocki
Author by

sligocki

Updated on September 17, 2022

Comments

  • sligocki
    sligocki over 1 year

    If I run emacs from the shell:

    $ emacs foo &
    

    and then kill that shell, emacs dies.

    How can I run a command so that it will not die when the shell dies?

    I found references to nohup, but that does not seem to help:

    $ nohup emacs foo &
    

    still kills emacs when shell dies.

  • sligocki
    sligocki over 13 years
    Ah, great setsid works. Sorry about not being clear. Yes I'm referring to X apps that do not actually run in the shell. Basically, I want to start up emacs (or any other process) from the shell, but I don't want it in any way tied to the shell. I'm just starting it there for convenience.
  • sligocki
    sligocki over 13 years
    Great! these all work for me. Nice to have some more tools in my arsenal.
  • user1686
    user1686 about 13 years
    @Hello: It would be no different from just (emacs). If the subshell is given a single command, the exec is implied, at least in case of bash. Same applies to bash -c 'foo' versus bash -c 'exec foo'. (However, note that emacs itself may be detaching from the terminal; gvim, for example, does this. It is better to test with a program with known behavior.)
  • Dave Abrahams
    Dave Abrahams almost 13 years
    Great to learn of the double-fork technique; thanks!
  • Paulb
    Paulb about 11 years
    Found this while trolling to fix an issue of my own. The (setsid emacs &) worked for me. Thanks for a well written answer.
  • Nemo
    Nemo almost 8 years
    This is a very good point. I needed the opposite, i.e. forking a subshell and proceed with other tasks without waiting for its completion, but screen -d -m sh -c "{do stuff } exit" makes much more sense.
  • Alexander Shukaev
    Alexander Shukaev about 4 years
    For the record, this by any means is not the well-known double fork for daemonization.