72

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?

4 Answers 4

123

What's better, a fish or a bicycle? nohup and 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 &
6
  • 34
    a bicycle > a fish Nov 4, 2016 at 16:26
  • 9
    I beg to differ. Fish is obviously a superior method of transportation if it can be implemented. Jan 3, 2017 at 1:54
  • 9
    @THISUSERNEEDSHELP But a bicycle is better food, surely? Jan 3, 2017 at 8:43
  • 5
    @GypsyCosmonaut After you run exec firefox, the shell is no longer running: it has been replaced by firefox. You can think of exec as combining exiting a program and starting a new one, but keeping the same process ID. The terminal keeps running because nothing told it to stop. When you later exit Firefox, the firefox process terminates. The terminal notices that its child process has exited and so it exits in turn. Jul 31, 2017 at 0:42
  • 9
    Give a man a fish and you feed him for a day. Give a man a bicycle and he can ride it to the supermarket and buy fish for a lifetime.
    – David
    Jan 17, 2018 at 8:01
22

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.

3
  • 1
    This answer appears to be correct. As other answers above say, normally exec replaces the running process, but that doesn't seem to happen when you use & to background the exec'd command. Neither in bash nor zsh.
    – Dan Pritts
    Jul 29, 2016 at 21:53
  • @DanPritts What do you mean with it does not happen? A background subprocess gets started and then replaced, so exec smth & is the same as (exec smth) &, isn't that what's happening?
    – phk
    Feb 1, 2017 at 19:11
  • 2
    I mean it doesn't get exec'd in the sense that you would normally think of (replacing the current running shell) - it just gets run as a background process. I guess it probably is the same as (exec smth) &. But I wouldn't expect it to be the same - I would expect it to be a syntax error, how can you exec a process (replacing yourself) and then background the exec'd process? You're not there to do it anymore.
    – Dan Pritts
    Feb 1, 2017 at 21:06
2

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

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

1
  • I too am not sure about what exec does. I mean… I understand what it’s supposed to do but I can see only a minor difference between doing script.sh & or exec script.sh &. In both case the command is executed in a child process, it doesn’t replace the calling process, see: paste.alacon.org/44474 (too long to copy it here in a comment…). What am I doing wrong?
    – Stéphane
    Nov 15, 2017 at 21:01
2

You can't compare nohup with 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.