5

I would like to know the purpose of nohup these days.

I ask because I read this

Nohup is short for “No Hangups.” It’s not a command that you run by itself. Nohup is a supplemental command that tells the Linux system not to stop another command once it has started. That means it’ll keep running until it’s done, even if the user that started it logs out. The syntax for nohup is simple and looks something like this:

nohup sh your-script.sh &

Notice the “&” at the end of the command. That moves the command to the background, freeing up the terminal that you’re working in.

Nohup works with just about any command that you run in the terminal. It can be run with custom scripts as well as standard system commands and command line utilities.

With using linux distributions such as SLES 11.4, or RHEL/CentOS 7.x, I can

  • remote log in to linux over the network via SSH
  • run the simple program below, or any other, doing ./a.out &
  • log out of linux; type exit in the putty SSH terminal
  • my sample program below, or any other including bash, csh, or tcsh shell scripts, run to completion just fine without the need for nohup
  • typing exit in putty to close an SSH session, I would think that qualifies as a logout?

Is there any purpose or value with nouhup today? Is it a kernel >= 3.x thing? For however long I can remember (kernel >= 2.6) I've never used nohup and have always just use & with no problems.

Can someone give me a practical scenario where nohup would be used?

#include <stdlib.h>
#include <stdio.h>

/*
    sample C code, to print numbers to a file named zz.tmp
    the numbers 0 to 29 over 30 seconds
*/

int main ( int argc, char *argv[] )
{
   FILE *fp;
   int i;

   i = 0;
   fp = fopen("zz.tmp", "w" );

   while ( i < 30 )
   {
      fprintf( fp, "%d\n", i++ );
      sleep( 1 );
   }
   fclose( fp );
   return 0;
}

mysleep.sh

#!/bin/bash

sleep 1000

On Centos 7.7, optiplex pc login with keyboard & mouse, my account is bash. I do nohup ./mysleep.sh and then control-z. When typing jobs I see [1]+ Stopped nohup ./mysleep.sh

A ps -ef | grep mysleep shows that process id existing, but if I close the terminal window via X in upper right corner, that process goes away so it seems nohup is not working?

8
  • Related - For which versions of linux does nohup serve a purpose Commented Feb 18, 2020 at 14:57
  • 1
    the comment there was made: on all linux/unix system the background jobs will be killed with a HUP signal upon log-out. I believe that to be not true.
    – ron
    Commented Feb 18, 2020 at 15:32
  • I can change it to while < 1000 and fprintf( stdout, "%d\n", i++ ); and it continues to run; albeit when I log back in it is not printing to the terminal but the program [process] is still running just fine. I experience this all the time running number crunching codes on linux at work- they write info to the terminal but the valued result ends up in a text file, we do crunchmynumbers.x > log.txt & and we do not need to use nohup.
    – ron
    Commented Feb 18, 2020 at 15:36
  • 2
    Related questions are unix.stackexchange.com/q/284470/5132 and unix.stackexchange.com/q/492465/5132 .
    – JdeBP
    Commented Feb 18, 2020 at 16:13
  • @JdeBP except that bash will resend the HUP signal to its jobs, independent of shopt -s huponexit or the job control features implemented by the OS. Using nohup is NOT only for the case where huponexit is set in bash.
    – user313992
    Commented Feb 18, 2020 at 19:17

2 Answers 2

5

remote log in to linux over the network via SSH ... log out of linux; type exit in the putty SSH terminal

Can someone give me a practical scenario where nohup would be used?

Sure. Assuming your shell is bash (see below why), instead of typing exit or ^D, type ~. at the beginning of a line, which will cause your ssh client to disconnect:

$ ssh localhost
ssh$ sleep 3600 &
[1] 5765
ssh$ ~.
ssh$ Connection to localhost closed.
$ ps 5765
  PID TTY      STAT   TIME COMMAND

You can use your program instead of sleep; and instead of disconnecting via ~., you can kill your ssh client or crash the machine it runs on. You want your process to survive this? Use nohup ;-)

Breaking the connection will cause the server process which manages its other end to exit, causing the kernel (any Unix/Linux kernel) to tear down the pseudo-terminal ssh had created, and to send a SIGHUP signal to the session leader (the bash shell), which according to the bash manual:

The shell exits by default upon receipt of a SIGHUP. Before exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped. Stopped jobs are sent SIGCONT to ensure that they receive the SIGHUP.

Many people confuse this bash feature with a) the regular job control thing implemented by the kernel, which will only send a SIGCONT/SIGHUP pair to the stopped, not to the running jobs [1] and b) another bash feature (shopt -s huponexit) which causes a login bash shell to send a SIGHUP to its jobs even when exiting normally (eg. via exit).

[1] a stopped job is a job (= process group) which contains at least one stopped process. A process is stopped as an effect of the default action of a signal like SIGTSTP, SIGSTOP, SIGTTIN or SIGTTOU. Processes which are "sleeping" on a blocking system call like read, nanosleep, select, etc are not considered stopped, but running.

Why nohup may not always help

nohup just sets the disposition of SIGHUP to ignore and does some redirections, it does not guarantee that the process will not be killed by other ways.

a) If the nohup .. job is stopped, an interactive bash will also send it a SIGTERM signal, not just a SIGHUP/SIGCONT pair:

If an attempt to exit bash is made while jobs are stopped [...] the shell prints a warning message [...] If a second attempt to exit is made without an intervening command, the shell does not print another warning, and any stopped jobs are terminated.

[terminated = sent a SIGTERM signal; this is another ksh/bash feature, not present in all shells]

All this can be worked around by simple tricks like double-forks and by creating a new session with setsid(1), but

b) systemd may also "clean up" a logged-out session by forcefully killing (with SIGTERM followed by SIGKILL) any left-over processes if its KillUserProcesses setting is on, which is the default in some distros.

4
  • I added to my original question. I am confused by what you are referring to as a stopped process. Are you saying a running processes is not affected by a SIGHUP therefore nohup is not applicable on something like ./a.out & which is likely to always be running and not be affected by a SIGHUP?
    – ron
    Commented Feb 18, 2020 at 20:50
  • 1. ps -ef | grep mysleep is not the right way to check if that process is still running: bash will optimize the last command, sleep 1000 to exec sleep 1000 -- which will run the sleep in the same process, whose name and command line will no longer include mysleep 2. I'm saying exactly the contrary of that: ./a.out & can be sent a SIGHUP if it's started from bash (or some other "advanced" shell which expands the job control implemented by the OS with its own actions).
    – user313992
    Commented Feb 18, 2020 at 21:06
  • @ron fwiw, your stopped mysleep.sh will be killed by a SIGTERM explicitly sent by bash, not by a SIGHUP, so starting it via nohup doesn't make any difference. An interactive bash also sends a SIGTERM to the stopped jobs, not just a SIGHUP + SIGCONT.
    – user313992
    Commented Feb 19, 2020 at 17:53
  • @ron I've added a section about why/when nohup may not help; another situation is when it's hup'ed before being able to ignore the sighup signal. But this is getting way off the original question and turning into a quirks and trivia collection. If the whole point of your Q was to "prove" that nohup is/was always useless and you can simply run foo & and log out and foo won't be hup'ed, THAT IS WRONG.
    – user313992
    Commented Feb 19, 2020 at 18:49
0

I always think of nohup as a sort poor man's daemon.
So do these folks: https://stackoverflow.com/questions/958249/whats-the-difference-between-nohup-and-a-daemon

It gets used as a way to code a shell daemon.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .