Work the Shell - Dealing with Signals

 in
By handling signals in your bash scripts, you can provide features that are otherwise difficult, such as telling your script to reread its configuration file after it's already been started.

right before the section where I don't want the Ctrl-Z to work, it'll ignore that first Ctrl-Z, then reset the signal handler and work as expected the second time you press that key.

More useful is to ignore all Ctrl-Z stop signals until you're ready to deal with them, and that's quite easily done with the minimalist:

trap : TSTP  # ignore Ctrl-Z requests

And, then when you're ready to receive them again:

trap - TSTP  # allow Ctrl-Z requests

Experimentation will show that there are some weird terminal buffering issues associated with SIGTSTP, however, so don't be surprised if you have a signal handler that has output. In this particular instance, it won't show up until the script quits.

Reading a Configuration File

Let's look at a more practical example. Say you have an admin script that is always supposed to be running as a dæmon, but occasionally you want to tweak its configuration file and have it reread its setup (a lot faster than killing and restarting it).

Further, let's use SIGUSR1 for this task, as that is its intended use, so we're using the kernel's signal handling subsystem in the manner it was intended.

Reading a configuration file might be something as simple as:

. $config

(Recall that using . means that any variables set in the secondary file affect the current shell, not a subshell. The source command does the same thing as the . command.)

Here's our script to experiment with this feature:

#!/bin/bash

config="our.config.file"
sigusr1()
{
  echo "(SIGUSR1: re-reading config file)"
  . $config
}

trap sigusr1 USR1       # catch -USR1 signal

echo "Daemon started. Assigned PID is $$"

. $config               # read it first time

while /usr/bin/true; do
  echo "Target number = $number"
  sleep 5
done

trap - USR1             # reset to be elegant

exit 0

We'll start with the configuration file containing number=5, then after 10–15 seconds, change it to number=1. Until we send the actual USR1 signal, however, the script just plugs along without a clue that it has changed:

$ ./test2.sh
Daemon started. Assigned PID is 25843
Target number = 5
Target number = 5
Target number = 5

Meanwhile, in another window, I've already edited the file, so I type in this command:

$ kill -USR1 25843

And, here's what happens in the main script window:

(SIGUSR1: re-reading config file)
Target number = 1
Target number = 1

Cool, eh?

I hope this exploration of signal handling in shell scripts is useful. I actually learned quite a bit about advanced handling as I researched the code here. I'm still a bit stymied about how to reset the output stream after catching a SIGTSTP, but I bet that some sharp Linux Journal reader will have an answer.

Dave Taylor has been hacking shell scripts for a really long time, 30 years. He's the author of the popular Wicked Cool Shell Scripts and can be found on Twitter as @DaveTaylor and more generally at www.DaveTaylorOnline.com.

______________________

Dave Taylor has been hacking shell scripts for over thirty years. Really. He's the author of the popular "Wicked Cool Shell Scripts" and can be found on Twitter as @DaveTaylor and more generally at www.DaveTaylorOnline.com.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Passing argument

Anonymous's picture

Hi all,
I wanted to know if it's possible to pass arguments to the configuration file when we invoke the command kill.

For example we want to change directory to a shell 1 from another shell 2, so:
# test.sh
sigusr1()
{
cd $1
}
trap "sigusr1" USR1

type command in shell 1:
$ ./test.sh

then, i would like type something like this in shell 2:
$ kill -USR1 10482 /home

In this way i can specify the new current directory directly from shell 2.

How can I do it? Is there another workaround??
Thanks

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix