I was reminded of signals in shell scripts, after reading some arcane Bash code a few months ago. What are signals, and how can they be used in shell scripts? The kernel sends signals to running processes about ongoing events. If you type
trap -l in your terminal you’ll a list of all available signals, with both their number and their name. Either one can be used to reference a given signal. See the Bash manual for more information. Note that
trap is also aware of
ERR signals that occur when programs like
tar exits with non zero status code.
I don’t remember what script caught my attention, but the gist of it is that you can easily monitor
SIGINT signals in a shell script, as you would do with other environmental variables or user input.
Without further ado, here’s a sample script which catch up eventual user interrupt (
Ctrl-C) when an external program is running :
#!/usr/bin/env bash trap "echo User interrupt; exit" SIGINT ghc -e 'iterate (\x -> ((1103515245 * x) + 12345 `mod` 2^31)) 1'
trap can also be wrapped in a Bash function. And of course, you can capture more than one signals.
import System.Random main = do g <- newStdGen (randoms g :: [Double])
A similar approach is discussed in this blog post. Other options are discussed on Stack Overflow. Another nice usage of the
trap command is to clean up intermediate or temporary files in case the program crashes. See an exemple in this article.
I don’t have a clear idea of how to use
trap for anything really involved in my Bash script, but I will surely consider using
trap to clean up messy files from now on. In particular, I think the foloowing might be useful near the top of some of my Bash files (e.g., before carrying out large bioinformatics stuff), to offer a proper garbage collector to my scripts:
trap "rm -f /tmp/out" EXIT SIGINT
♪ Keith Jarrett • You’ve Changed