Write a bash script to keep programs/scripts running after logoff

Leading up to getting our scripts to run as daemons, we need to know how to keep commands running after a user logs off (or better yet, have them started by the system itself (we will look at this in more detail later). When a user logs in, a session for that user is created, but when they log off—unless the system owns it, processes and scripts typically get killed or closed.

This recipe is about keeping your scripts and activities running in the background after you log off.

Prerequisites

Besides having a terminal open, we need to remember a few concepts:

  • When a user logs off, any apps or processes owned by the current user will exit (the shell will send a signal)
  • The shell is configurable to not send a shutdown signal to processes
  • Applications and scripts use stdin and stdout for the usual operations
  • Applications or scripts in the background can be referred to as jobs

One neat way is by using &, which is used this way: $ bash runforver.sh &. Unfortunately, using only this technique, we are back at square one—our binary still dies when we exit. Therefore, we need to use programs such as screendisown, and sighup.

Note:

The screen command is not available on all systems. It is recommended that we use another command in case screen is absent (it is still useful to know!).

Write Script:

Let’s start our activity as follows:

Open a terminal and create the loop_and_print.sh script:

loop_and_print.sh

#!/bin/bash 
EXIT_PLEASE=0 
INC=0 
until [ ${EXIT_PLEASE} != 0 ] # EXIT_PLEASE is set to 0, until will never be satisfied 
do 
	echo "Boo $INC" > /dev/null 
	INC=$((INC + 1)) 
	sleep 1 
done 
exit 0

Open a terminal and run the following commands:

$ bash loop_and_print.sh & 
$ ps aux | grep loop_and_print.sh # Take note of the PID - write it down

Next, log off, then log in and run the following command in a new terminal:

$ ps aux | grep loop_and_print.sh # Take note of the PID - write it down

Can you find the process running? Next, run the following command:

$ bash loop_and_print.sh & # note the PID againg 
$ disown

Next, log off, then log in and run the following command in a new terminal:

$ ps aux | grep loop_and_print.sh # Take note of the PID - write it down

Next, run the following command:

$ nohup bash loop_and_print.sh &

Next, log off, then log in and run the following command in a new terminal:

$ ps aux | grep loop_and_print.sh # Take note of the PID - write it down

How script work:

In step 1, we opened a terminal and created the loop_and_print.sh script. This script merely loops forever, printing as it does.

The following commands will use the loop_and_print.sh script and run in the background as a job. The ps command outputs process information and is piped through grep to simplify the output. In the command, we can see the process ID (PID) next to the username column. Keep note of PIDs so that you can kill zombie processes or stop unnecessary applications:

$ bash loop_and_print.sh & 
[1]4510 
$ ps aux | grep loop_and_print.sh # Take note of the PID - write it down 
rbrash 4510 0.0 0.0 12548 3024 pts/2 S 12:58 0:00 bash loop_and_print.sh

Logging back on and running the ps command will produce zero results. This is because the script we put into the background using & has been sent a signal to shutdown or die. 

Again, we run the loop_and_print.sh script; command puts it into the background, and disown removes the the background process(es) from the known list of jobs. This disconnects the script and all output from any terminal. 

Upon logging back in and using the ps command, you shall see the PID of the command:

rbrash 8097 0.0 0.0 12548 3024 pts/2 S 13:02 0:00 bash loop_and_print.sh

The nohup command is similar to the disown command, except that it explicitly disconnects the script from the current shell. It is also different from disown because nohup allows you still retain output from the script, which is accessible by other applications after the fact in the nohup.out file:

$ nohup bash loop_and_print.sh & 
[2] 14256 
$ nohup: ignoring input and appending output to 'nohup.out'

Upon logging back in and using the ps command, you shall see the PIDs of the two scripts that survived the logoff:

$ ps aux | grep loop_and_print.sh 
rbrash 4510 0.0 0.0 12548 3024 pts/2 S 12:58 0:00 bash loop_and_print.sh 
rbrash 14256 0.0 0.0 12548 3024 pts/2 S 13:02 0:00 bash loop_and_print.sh

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

Related Articles