I'm still pretty new to bash scripting, and I'm having a hard time figuring out why this simple trap is not working as expected.
Goal - create an optional waiting period that can be skipped by pressing CTRL+C.
Expected result of pressing CTRL+C - immediately echo "No time for napping!" and exit.
Actual result of pressing CTRL+C - immediately echo "naptime over." and exit.
#!/bin/bash
nonap() {
echo "No time for napping!"
exit
}
trap nonap INT
echo "Sleeping for 5 seconds, hit ctrl-c to proceed now."
sleep 5
echo "Naptime over."
Why is my trap function not invoked?
I just tried it (on an ancient RHEL Linux with bash 3.2.25) and saved your code in
trap.sh
, ranbash trap.sh
, and got:followed by:
when I interrupted, as you expected. When I let it run without interrupting, I got the expected message:
You then commented:
To which I responded:
How are you running this script, then? Using
source
or.
to read it? Ah, yes; you must be. I just tried that, and the interrupt while sourcing gave meNaptime over.
; typing another interrupt though gave meNo time for napping!
and the shell exited. The second time it behaved as expected; I'm not sure what's up with the interrupt while dotting the script. That is unexpected behaviour.Why did you want to source or dot this? Why not just use it as a plain old script?
Well, there's a "Doctor, Doctor, it hurts when I hit my head against the wall" component to the following advice, but there's also basic pragmatism in there too.
You use
source
(in C shell orbash
) or.
(in Bourne, Korn, POSIX shells orbash
) to have the script affect the environment of the invoking shell, rather than running as a sub-shell. The giveaway to solving the problem (albeit largely by fluke) was when you reported that after running the script, you had the function defined; that can't happen unless you were usingsource
. In this case, it is fairly clear that you do not want thetrap
set in the calling shell. When I ran it (from aksh
with promptToru JL:
), I got:The 'No time for napping!' message appeared when I hit the interrupt key again, and it terminated the
bash
I'd run. If you continue to use it withsource
, you would want to addtrap INT
to the end of the script, and you might also want to undefine the the function.However, you are much better off isolating it all in a shell and running it as a sub-process, I think.
But...your finding that this sort of thing plays funny games when the script is sourced is interesting. It's a minor anomaly in the behaviour of
bash
. I'm not sure it rises to the level of 'bug'; I'd have to read a lot of manual rather carefully (probably several times) and consult with other knowledgeable people before claiming 'bug'.I'm not sure it will be any consolation, but I tried
ksh
on your script with.
and it worked as we'd both expect: