37

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
  • 849
  • 1
  • 9
  • 11

3 Answers3

47

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

Infiltrator
  • 103
  • 3
u1686_grawity
  • 426,297
  • 64
  • 894
  • 966
  • Great! these all work for me. Nice to have some more tools in my arsenal. – sligocki Aug 06 '10 at 15:54
  • Hm... would `(exec emacs)` work? – Hello71 Apr 27 '11 at 20:51
  • @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.) – u1686_grawity Apr 27 '11 at 21:41
  • Great to learn of the double-fork technique; thanks! – Dave Abrahams Jul 07 '11 at 15:35
  • Found this while trolling to fix an issue of my own. The (setsid emacs &) worked for me. Thanks for a well written answer. – Paulb Mar 22 '13 at 21:57
  • For the record, this by any means is not the well-known double fork for daemonization. – Alexander Shukaev Apr 25 '20 at 13:52
  • By the way, does anybody know how to combine this with something like `&>/dev/null` to get rid of the outpur in the console too? I tried nad it seems to mess up with the process. – sup Sep 11 '22 at 02:47
16

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 &

Rich Homolka
  • 31,057
  • 6
  • 55
  • 80
  • 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 Aug 04 '10 at 18:48
5

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

Josh K
  • 12,747
  • 7
  • 41
  • 58
  • Screen allows you to get back into the process later with `screen -r` if you use `Ctrl-A Ctrl-D` to disconnect it before logging out. – Broam Mar 22 '12 at 15:25
  • 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. – Nemo Jun 17 '16 at 15:47