How do I fork a process that doesn't die when shell exits?
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, anddisown
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 ifsetsid
is used in ash
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
.
Related videos on Youtube
sligocki
Updated on September 17, 2022Comments
-
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 over 13 yearsAh, 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 over 13 yearsGreat! these all work for me. Nice to have some more tools in my arsenal.
-
user1686 about 13 years@Hello: It would be no different from just
(emacs)
. If the subshell is given a single command, theexec
is implied, at least in case ofbash
. Same applies tobash -c 'foo'
versusbash -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 almost 13 yearsGreat to learn of the double-fork technique; thanks!
-
Paulb about 11 yearsFound this while trolling to fix an issue of my own. The (setsid emacs &) worked for me. Thanks for a well written answer.
-
Nemo almost 8 yearsThis 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 about 4 yearsFor the record, this by any means is not the well-known double fork for daemonization.