How to Leave scripts running when you logoff, and exit nicely when sent a SIGTERM signal



Table of Contents

by Ross Moffatt, October 2009

Overview

I suppose this article is about the trap command.  Mainly to highlight its usefulness as opposed to using the nohup command, cron commad, at command, or other ways to have a script picked up by the init process as a parent.  I also show the usefulness of trapping the SIGTERM, 15, signal and running commands just before a script exits.

 
To start off, here is a simple script that counts up numbers into a file. Let's call it MyShellScript, and remember to give it execute permissions.  It runs as a continuous loop and needs a Ctrl-C or a kill <PID>, or you need to log out to stop it from running.

#!/bin/bash

# MyShellScript

i=0
  echo $i > MyShellScript.out
while :
do
  i=`expr $i + "1"`
  echo $i >> MyShellScript.out
  sleep 5
done

Leaving scripts running when you logoff

The standard way to run a script in the background is to use the & character at the end of the command line, like this.

$ ./myShellScript &

When you run a script, its Parent Process ID (PPID) is your shell's Process ID (PID).  This can be seen by looking at the process list.

$ ps -ef | grep MyShellScript
    ross  1300  1281   0 13:26:15 pts/3       0:00 /bin/bash ./MyShellScript

This shows the user "ross" is the process owner, the PID is 1300, and the PPID is 1281.

Use kill <PID> to stop the script running, for example, in my case:
 

$ kill 1300
[1]+  Terminated              ./MyShellScript

To have the script "picked up" by the init process on logout, trap the SIGHUP, 1, signal by adding a trap command to the script.
 

#!/bin/bash

# MyShellScript

trap "" 1

i=0
  echo $i > MyShellScript.out
while :
do
  i=`expr $i + "1"`
  echo $i >> MyShellScript.out
  sleep 5
done

Now run the script, log off, and log back in again.  Doing a process list shows MyShellScript still running, with a PPID of 1, owned by init.  When you log off, the session may seem to hang and you may need to disconnect the session depending upon the terminal emulation program you are using.

# ps -ef | grep MyShellScript
   ross  1421     1   0 13:34:14 ?           0:00 /bin/bash ./MyShellScript

So now the PPID is 1, which is the init process, as can be seen as follows.
 

$ ps -ef|grep init
    root     1     0   0 11:21:25 ?           0:00 /sbin/init

OK, so now the only way to stop this process from running is to use the kill <pid> command, for example, in my case:
 

$ kill 1421


Exiting nicely when a script is sent a SIGTERM signal

By default, a signal SIGTERM, 15, is sent; so let's trap it.
Note: The trap command looks for the matching ", and other special characters need to be escaped.  That's why I create the shell variable with the special character ' escaped using a \.  So here is MyShellScript with a few more lines added.

#!/bin/bash

# MyShellScript

MyMessage="I don\'t want to stop"

trap "" 1
trap "echo $MyMessage" 15

i=0
  echo $i > MyShellScript.out
while :
do
  i=`expr $i + "1"`
  echo $i >> MyShellScript.out
  sleep 5
done

So let's run this script, and send it a kill SIGTERM signal.

$ ./MyShellScript &
[1] 1674

$ kill 1674
I don't want to stop

Checking the process list shows our script still running, and lets set it a SIGKILL signal.

$ ps -ef|grep MyShellScript
    ross  1674  1434   0 13:50:02 pts/4       0:00 /bin/bash ./MyShellScript

$ kill -9 1674
[1]+  Killed                  ./MyShellScript

Now lets exit nicely after receiving the SIGTERM signal.  So here is the modified MyShellScript.

#!/bin/bash

MyMessage="Stopping"

trap "" 1
trap "echo $MyMessage
exit 0" 15

i=0
  echo $i > MyShellScript.out
while :
do
  i=`expr $i + "1"`
  echo $i >> MyShellScript.out
  sleep 5
done

Now let's run this script and send it a SIGTERM signal. 

$ ./MyShellScript &
[1] 1729
$ kill 1729

Stopping

[1]+  Done                    ./MyShellScript

A number of commands can be run upon receiving the SIGTERM trap, such as writing log messages, deleting temporary files, etc.

List of signals

By using the kill command, a list of signals can be obtained.
 

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
 5) SIGTRAP      6) SIGABRT      7) SIGEMT       8) SIGFPE
 9) SIGKILL     10) SIGBUS      11) SIGSEGV     12) SIGSYS
13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGUSR1
17) SIGUSR2     18) SIGCHLD     19) SIGPWR      20) SIGWINCH
21) SIGURG      22) SIGIO       23) SIGSTOP     24) SIGTSTP
25) SIGCONT     26) SIGTTIN     27) SIGTTOU     28) SIGVTALRM
29) SIGPROF     30) SIGXCPU     31) SIGXFSZ     32) SIGWAITING
33) SIGLWP      34) SIGFREEZE   35) SIGTHAW     36) SIGCANCEL
37) SIGLOST     38) SIGXRES     41) SIGRTMIN    42) SIGRTMIN+1
43) SIGRTMIN+2  44) SIGRTMIN+3  45) SIGRTMAX-3  46) SIGRTMAX-2
47) SIGRTMAX-1  48) SIGRTMAX

Conclusion

 
 In this article, I have highlighted the usefulness of the trap command to trap the SIGTERM, 1, signal to enable scripts to keep running after the user who started the process logs off.  I have also showed the usefulness of trapping the SIGTERM, 15, signal to exit a running script nicely allowing tidy-up commands to run before exiting.  Also, a quick note: The SIGKILL, 9, signal cannot be trapped.

About The Author

Ross Moffatt has been a UNIX System Administrator for more than 10 years, and can be contacted at ross.stuff@telstra.com.

Labels

bigadmin bigadmin Delete
sysadmin sysadmin Delete
trap trap Delete
sigterm sigterm Delete
script script Delete
pid pid Delete
ppid ppid Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

Sign up or Log in to add a comment or watch this page.


The individuals who post here are part of the extended Sun Microsystems community and they might not be employed or in any way formally affiliated with Sun Microsystems. The opinions expressed here are their own, are not necessarily reviewed in advance by anyone but the individual authors, and neither Sun nor any other party necessarily agrees with them.

Copyright 1994-2009 Sun Microsystems, Inc.
Powered by Atlassian Confluence
Sun Guidelines on Public Discourse Privacy Policy Terms of Use Trademarks Site Map Employment Investor Relations Contact