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