I know that,
nohup being a binary, it can be reached from any shell. But the
exec built-in probably exists in every shell.
Is there a reason to prefer one of them, to the other?
What's better, a fish or a bicycle?
exec do different things.
exec replaces the shell with another program. Using
exec in a simple background job isn't useful:
exec myprogram; more stuff replaces the shell with
myprogram and so doesn't run
more stuff, unlike
myprogram; more stuff which runs
more stuff when
myprogram terminates; but
exec myprogram & more stuff starts
myprogram in the background and then runs
more stuff, just like
myprogram & more stuff.
nohup runs the specificed program with the SIGHUP signal ignored. When a terminal is closed, the kernel sends SIGHUP to the controlling process in that terminal (i.e. the shell). The shell in turn sends SIGHUP to all the jobs running in the background. Running a job with
nohup prevents it from being killed in this way if the terminal dies (which happens e.g. if you were logged in remotely and the connection drops, or if you close your terminal emulator).
nohup also redirects the program's output to the file
nohup.out. This avoids the program dying because it isn't able to write to its output or error output. Note that
nohup doesn't redirect the input. To fully disconnect a program from the terminal where you launched it, use
nohup myprogram </dev/null >myprogram.log 2>&1 &
exec & => executes a process as a background process so you may continue using the same terminal for other jobs.
nohup => avoids all SIGHUP(terminate signal) and continues execution even if you terminal is closed.
exec process dies when a
SIGHUP is received, but
nohup process continues.
The shell built in command
exec <command> replaces the shell with
<command>, no new process, no new PID is created. After completion of
<command> normally your terminal will close. By running it in the background first a subshell is created, which then similarly is immediately replaced by
nohup <command> command will run
<command> but immume to hangups (kill -s 1) so it will not be terminated when the shell, the terminal from which it was started is, is closed. By running it in the background first a subshell is created and the command runs in the background, returning you to the prompt.
In scripting the immediate effect is more or less the same though,
<command> is started by your script and the script will continue without waiting for
<command> to start, to send output or to complete.
You can't compare
exec. When you run an executable with
nohup, the process won't be killed when you logout (ssh session); usually
nohup is used with
nice to run processes on a lower priority. The
HUP signal is, by convention, the way a terminal warns dependent processes of logout