I'm working on a BASH script (see below), that will vomit out the keycodes on keypress for my own use in a different, unrelated script. Contained therein is a trap command for SIGINT which, amongst other things, echos out a "Killed by user" message. The script works fine, the trap works fine, even the Ctrl+C to exit does what I was hoping it would.

Thing is, from that point thereafter, every time I hit Ctrl+C the "Killed by user" message is echoed to the screen AGAIN, suggesting the trap I set earlier is still in effect. It's not HURTING anything per se, but it's kind of obnoxious, and makes me worried I've left other background processes in effect.

My initial thought is I need to run some untrap command to relinquish the observer, but, quite aside from the fact I can find no mention of such a command in the manpages, I suspect this is symptomatic of the possibility I'm missing something more fundamental than that in how the script is actually affecting the shell instance. In short: I'm not married to the idea of an untrap resolution; any thoughts would be most welcome.

Full contents of script:


function capture_input(){
    export CAPPING=true
    export SSTTY
    if [[ "$(stty --save 2>/dev/null)" == "" ]]; then
        SSTTY="$(stty -g)" #BASH
        SSTTY="$(stty --save)" #ZSH
    trap sigint_handler SIGINT

function keycap(){
    [[ "$CAPPING" == false ]] && return 1
    command stty -echo -icanon -icrnl time 0 min 0
    while [[ "x$keypress" == "x" && "$CAPPING" == true ]]; do
        echo -ne '>\r'
        keypress="$(cat -v)"

    echo "KEY :: '$keypress'"
    [[ "$CAPPING" == true ]] && keycap "$SSTTY"

function sigint_handler(){
    echo "Killed by user"
    stty $SSTTY
    return 1


Oh! Also: the CAPPING variable nonsense there is a consequence of these oddities I'm experiencing related to the SIGINT. Without it, it would display its message, then promptly drop right back into the loop. CAPPING was a crude attempt to enforce the interrupt, and, while successful, is something I suspect relates to what I'm missing here.

Platform: MacOS (aarch64-apple-darwin20.2.0) BASH version: GNU bash, version 5.1.4(1)-release running from within ZSH 5.8 (Ideally I'd like to get the script running correctly in both).

  • @zevzek - I'm sorry, by INT to you mean "the integer value corresponding to SIGINT" (so trap - 2)? Or the INT portion of SIGINT (so trap - TERM for SIGTERM as a for-instance)? And that's a single dash, correct? Neither yield any response to STDOUT.
    – NerdyDeeds
    Nov 13 at 5:50
  • @zevzek Never mind, experimentation yielded the result. Did you wanna post it as an actual answer so I can give you credit?
    – NerdyDeeds
    Nov 13 at 5:55
  • Also, trap '' INT (an empty action) sets the signal to "ignored". Both variants are in the first paragraph under trap, in section 4.1 of the Bash Reference Manual. Nov 13 at 10:31
  • Why thank you Paul! I can honestly say it didn't occur to me to look there, particularly since it comes up in the list of built-ins for the shell with no explanation. On the subject: is there a way to navigate directly to its man entry, rather than hitting space/page down 45 times?
    – NerdyDeeds
    Nov 14 at 8:33
  • 2
    @NerdyDeeds Has your problem been solved? If so, don't leave your question open as "unanswered". Instead, either close your question or post your own answer and accept it. Nov 15 at 17:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.