When i use 'trap' combined with select loop, namely when i try to hit CTRL+C to break out while options are displayed, it will just print ^C in terminal. If i remove 'trap' from script it will normally exit out, that is it will accept CTRL+C.
I've tested this on two different versions of bash (One shipped with CentOS and one shipped with Fedora), and i have an issue with the one from Fedora (4.4.23(1)-release). Bash version 4.2.46(2)-release that is shipped with CentOS seems to work fine. I've also tested this on local terminal and remote (via ssh). And problem is always on Fedora side.
I will post code to see what I'm talking about
This one doesn't work:
#!/bin/bash
trap exit SIGINT
select opt in One Two Three; do
break
done
If i were to remove the entire 'trap exit SIGINT' line, it will work fine and accept CTRL+C without issues.
Any ideas how to fix or bypass this ?
Best Answer
You can bypass it by turning on the posix mode, either with the
--posix
option, or temporarily withset -o posix
:For an explanation for this behavior, you can look at the
zread()
function, which is used by theread
builtin (which is also called internally by bash inselect
):For some special reason, the
executing_builtin
is only set when theread
builtin is called explicitly, not when it's called byselect
. This very much looks like a bug, not something deliberate.When running in posix mode, a signal will cancel the
read
builtin. In that case,zreadintr()
is called, which unlikezread()
, is not re-calling the interruptedread(2)
syscall after running the traps. Seebuiltins/read.def
:More details about bash's "restarting"
read
builtin here.