trap "stty echo" INT has no effect when used with read -s

290 views Asked by At

Given this bash script:

stty -echo
echo $(stty)

reset() {
        stty echo
        echo $(stty)
        exit
}

trap reset int
read -s
sleep 10

I expected the echo option to be enabled, but after pressing ctrlc it is still disabled, even though I have ran stty echo (as you can see in the output by the reset function).

terminal picture

1

There are 1 answers

2
Szymon Marczak On BEST ANSWER

As @KamilCuk has noticed in the comments, read saves the configuration and restores it when the process exists. That results in modifications done while read was running being discarded. The solution is to restore the defaults before running read and redoing them after read finishes.

stty -echo
echo $(stty)

reset() {
        stty echo
        echo $(stty)
        exit
}

trap reset int

stty echo # This line has been added
read -s
echo read finished
stty -echo # This line has been added

sleep 10

@JonathanLeffler also noted that

It can be useful to use old=$(stty -g) to capture the current terminal settings, and then use stty "$old" to reinstate those settings.

Explaination:

Using it allows you to reinstate the exact terminal settings when stty -g was invoked. This can be more reliable than undoing changes with stty -echo etc.

Which I think is the more proper solution, as the stty may run in no-echo mode by default.