Trap not working in a shell script?

I am currently writing a script on OS X that needs to catch SIGTERM to kill some child processes before exiting. For the sake of this question, I've reduced it to the following minimal example, which for some reason doesn't work the way I would expect it to:

#!/bin/sh

function shutdown()
{
  touch foo.txt
  exit 0
}

trap shutdown TERM
su -l myusername -c "sleep 9999"

      

I run this script in one terminal window, then switch to another, and ps -aef outputs this:

  502   857   645   0 11:38PM ttys001    0:00.00 /bin/sh ./foo.sh
    0   858   857   0 11:38PM ttys001    0:00.02 su -l myusername -c sleep 9999
  502   859   858   0 11:38PM ttys001    0:00.00 sleep 9999

      

From this second window, I issue "kill -15 857", but the trap never runs. The script remains blocked on the "su" command.

Any idea why? I feel like this is something simple.

+3


source to share


1 answer


The bash manual states that:

If bash is waiting for a command to complete and receives a hook set signal, the hook will not run until the command is complete.

Like gniourf_gniourf , it is a POSIX specification for signals in wrappers .

You can check this by capturing, for example, SIGUSR1 instead of SIGTERM; you will see that kill -TERM

will kill the process again.



The solution is to run the command in the background and then wait

to complete it. In this case it trap

will work. Try the following:

#! /bin/bash

shutdown()
{
    touch foo.txt
    exit 0
}

trap shutdown TERM
su -l myusername -c "sleep 9999" &    # On Ubuntu: sudo su
wait

      

You will have two problems: su

unable to prompt for a password in the foreground; you will have to manually kill su

.

+9


source







All Articles