Trying to restore echo when user interrupts a read from this bash shell function that they call from their shell:
setsecret() { stty -echo; read $1; stty echo; }
If you type ctrl-c during the read, the stty echo is not called, so I have to do it manually from the shell. Not a huge deal, but would prefer to not have to do this.
So far I have this:
break_from_setsecret() {
stty echo
trap - INT
echo "Press ENTER alone to cancel command (instead of Ctrl-C, which would mess up your terminal echo)"
}
setsecret() {
trap break_from_setsecret INT
echo "Type in a secret and press ENTER (press ENTER alone to cancel the commmand):"
stty -echo
read $1
stty echo
}
This is a net improvement over having to type "stty echo" while echo is off in the shell. But not perfect:
- the read actually resumes after the handler returns; so you have to press ENTER (per the message I added in handler)
- if instead of pressing ENTER, you type ctrl-c a second time (ie after the handler echo), the shell exits (but if you press enter and the command ends, you can type ctrl-c fine in the shell, everything is back to normal).
I tried cancelling the read by "re-raising" the signal from the break_from_setsecret via kill -n INT $$ but that did not work (it exits my shell). Is there a way to do that?
Alternatively, if there was a way to register a cleanup function that setsecret() would call when it ends (even from ctrl-c), but I don't think bash supports this. I tried with trap ERR instead of INT but handler does not get called on a ctrl-c during read (eventhough if you ctrl-c during a normal read, the exit code of read is non-zero).
EDIT: Latest workaround is to gobble up the ctrl-c by changing the handler to this:
break_from_setsecret() {
echo "Press ENTER alone to cancel command (instead of Ctrl-C, which would mess up your terminal echo)"
}
But it would still be nice to have the cleanup approach work.