2 minutes
How to shut down a shellscript gracefully with trap EXIT
Shell script shutdown behavior
Imagine you’re running some long-running process, such as a database server or an application that needs to write its state to a file before shutting down.
Let’s use the simple server as a hypothetical example even though it doesn’t write anything to disk.
ruby -run -e httpd . -p 8080
If you just run the program by itself, it does work as expected. When you Ctrl-C
in the window that started the program, it gets the opportunity to do run some shutdown routines before terminating.
But if you wrap your application in a shell script, to add some additional checks or gathering input data perhaps, then it starts acting up. Turns out, since the application is now a subprocess of the script, it does not automatically get the SIGINT signal sent by the user with Ctrl-C
. Instead the signal goes to the shellscript, which kills of its subprocess in a more forceful way directly or indirectly, so that the application’s cleanup routines never get a chance to run.
run.sh
#!/bin/bash
set -e
cd $(dirname $0)
ruby -run -e httpd . -p 8080
Here’s how to use trap ... EXIT
to fix it
#!/bin/bash
set -e
function shutdown {
echo "Shutting down application from entry script..."
# ps aux
kill -2 $pid
wait $pid
echo "Shutdown completed successfully"
}
trap shutdown EXIT
ruby -run -e httpd . -p 8080 &
pid=$!
echo "Got application pid $pid"
wait $pid