1. Overview

Sometimes we run a command in the background as it may take a long time to finish. Ordinarily, if we log out while a background job is running, it gets terminated. However, we can use the nohup command to run a job that continues to run even if we log out.

Later, after logging out and logging in again, we might need to get the process identifier (PID) of the process that we had started in the background. For example, we may want to check if it’s still running.

In this tutorial, we’ll see how to get the PID of a background process started with nohup. We’ll also touch upon the huponexit option of the shopt command as it’s related to nohup.

2. Getting the PID of a Process Executed With the nohup Command

Let’s start a process in the background using nohup:

$ bash -l
$ nohup sleep infinity >& nohup.out &
[1] 20634
$ exit
logout
$

First, we started an interactive login shell using the bash command. The -l option of bash starts a shell as a login shell.

Then, we started a process, sleep infinity, in the background using nohup. We redirected the standard output and the standard error to the file nohup.out.

Finally, we exited from the interactive login shell using the exit command.

2.1. Saving the PID While Starting the Process

When we started the process using nohup above, the output of the command execution was [1] 20634. The number within the brackets, 1,  is the job ID. The number after the job ID, 20634, is the PID of the process spawned by executing the sleep infinity command.

We can use this PID later to check or control the process. For example, we can check whether the process is still running:

$ ps -ef -o pid | grep 20634
20634

Instead of manually noting down the PID of the process in order to remember it, we can save the PID into a file and use it later:

$ bash -l
$ nohup sleep infinity >& nohup.out &
[1] 21443
$ echo $! > $HOME/pid.nohup
$ exit
logout
$ cat $HOME/pid.nohup
21443

Now, we have the PID stored in the file $HOME/pid.nohup. $! is the PID of the last command which ran in the background, sleep infinity in our case.

So, we can use this PID later, for example, to kill the process:

$ kill -9 `cat $HOME/pid.nohup`
[1]+  Killed                  nohup sleep infinity

2.2. Using the ps Command

If we forget to note the PID of the process while starting it with nohup, we can get it later using ps. Let’s search the command sleep infinity in the existing processes:

$ ps -ef | grep "sleep infinity"
alice     21443       1  0  00:27 pts/0    00:00:00 sleep infinity
alice     21673    4672  0  00:27 pts/0    00:00:00 grep sleep infinity

Here, we filtered the output of ps using grep. We didn’t use the term “nohup” in the search as it doesn’t appear in the output of the ps command.

Since the grep “sleep infinity” command within the pipe is also listed in the output, we can filter it further using grep:

$ ps -ef | grep "sleep infinity" | grep -v grep
alice     21443       1  0  00:27 pts/0    00:00:00 sleep infinity

Finally, we can print only the PID of the process using the awk command:

$ ps -ef | grep "sleep infinity" | grep -v grep | awk '{print $2}'
21443

2.3. Using the pgrep Command

Alternatively, if we forget to note the PID of the process after starting it with nohup, we can also use the pgrep command:

$ pgrep -a sleep
21443 sleep infinity

Here, the -a option of pgrep prints the command together with its PID.

3. The huponexit Option of the shopt Command

Let’s once more spawn a process in the background in an interactive login shell and log out. But, in this case, we’ll start the process without nohup:

$ bash -l
$ sleep infinity &
[1] 25101
$ exit
logout
$

Let’s check whether the process is still running:

$ ps -ef -o pid | grep 25101
25101

It seems that the process is still running even though we logged out from the interactive login shell. So, does that mean that we don’t have to use nohup if we want a background process to continue running after logging out?

The answer is that we should use nohup if we want portability. Just running the command in the background without nohup may not always work.

In fact, this issue is related to a shell option, huponexit. We can check the value of this option with the shopt command:

$ shopt | grep huponexit
huponexit       off

The shopt command is used for setting and displaying several shell options. If the huponexit option is off, Bash doesn’t send SIGHUP signals to the already running processes spawned in that session when the interactive login shell exits. That’s why the process we spawned by executing the sleep infinity command was still alive after terminating the login shell with the exit command.

It’s possible to enable and disable the huponexit option. We can use the -s option to enable it and the -u option to disable it:

$ shopt -s huponexit
$ shopt | grep huponexit
huponexit       on
$ shopt -u huponexit
huponexit       off

Now, let’s enable the huponexit option and check the behavior:

$ bash -l
$ shopt –s huponexit
$ shopt | grep huponexit
huponexit       on
$ sleep infinity &
[1] 26238
$ exit
logout
$ ps –ef –o pid | grep 26238
$

Now, the process is not alive after we log out of the login shell because the kernel sends the signal SIGHUP to the process while logging out. Therefore, the process terminated when it received this signal.

4. Conclusion

In this article, we discussed how to get the PID of a process executed with the nohup command.

We can note down the PID while executing the command with nohup. However, it is possible to obtain the PID later using the ps and the pgrep commands.

We also touched upon the huponexit option of the shopt command. The kernel sends the signal SIGHUP to the running processes of a shell while logging out if the value of this option is on.