why is this simple bash trap failing
bash, bash-trap, shell-trap
Solution
I just tried it (on an ancient RHEL Linux with bash 3.2.25) and saved your code in `trap.sh`, ran `bash trap.sh`, and got:
Sleeping for 5 seconds, hit ctrl-c to proceed now.
followed by:
No time for napping!
when I interrupted, as you expected. When I let it run without interrupting, I got the expected message:
Naptime over.
You then commented:
At least I know it should work as expected. I'm using the latest version of Tinycore Linux with GNU bash, version 4.0.33(1)-release (i686-pc-linux-gnu). Upon opening a new terminal, `declare -f nonap` and `trap` both return no output. After running this script and getting the "Naptime over." output, `trap` returns `trap -- 'nonap' SIGINT` and `declare -f nonap` returns the function as defined in my script.
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 me `Naptime over.`; typing another interrupt though gave me `No 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?
No reason to source...I was just using that to run it while testing. I guess I've never run into any anomalies like this when using . before, but I'm still a newb too. I am seeing the same results you are, and it works as expected on the first interrupt if I run it with bash.
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 or `bash`) or `.` (in Bourne, Korn, POSIX shells or `bash`) 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 using `source`. In this case, it is fairly clear that you do not want the `trap` set in the calling shell. When I ran it (from a `ksh` with prompt `Toru JL:`), I got:
Toru JL: bash
bash-3.2$ trap
bash-3.2$ source trap.sh
Sleeping for 5 seconds, hit ctrl-c to proceed now.
Naptime over.
bash-3.2$ trap
trap -- 'nonap' INT
bash-3.2$ No time for napping!
Toru JL:
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 with `source`, you would want to add `trap 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:
Toru JL: ksh
$ . trap.sh
Sleeping for 5 seconds, hit ctrl-c to proceed now.
No time for napping!
Toru JL:
Problem
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?