Question

Take this script

#!/bin/sh

fd ()
{
  echo Hello world
  exit
}

trap fd EXIT INT

for g in {1..5}
do
  echo foo
  sleep 1
done

I would like fd to fire once, either from Control-C or if the script exits normally. However if you hit Control-C it will run twice. How can I fix this?

Was it helpful?

Solution

Do cascading traps. exit 127 will run the EXIT trap and set the exit code to 127, so you can say

#!/bin/sh

fd () {
  echo Hello world
  # No explicit exit here!
}

trap fd EXIT
trap 'exit 127' INT

I remember learning this from other people's scripts after struggling with various workarounds to your problem for several years. After that, I have noticed that some tutorials do explain this technique. But it is not documented clearly in e.g. the Bash manual page IMHO. (Or it wasn't when I needed it. Maybe some things don't change in 15 years ... :-)

OTHER TIPS

Inspired by pst’s comment

fd ()
{
  echo Hello world
  trap - EXIT INT
  exit
}

what about in redefining trap default?

#!/bin/sh

fd () {
   echo Hello world
   trap - EXIT
   exit 127
}

trap fd INT EXIT
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top