陷阱 "stty echo" INT 与 read -s 一起使用时无效

问题描述

给定这个 bash 脚本:

stty -echo
echo $(stty)

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

trap reset int
read -s
sleep 10

我希望启用 echo 选项,但是在按下 ctrlc 后,它仍然被禁用,即使我已经运行了 stty echo(你可以请参见 reset 函数输出)。

terminal picture

解决方法

正如评论中的@KamilCuk has noticedread 保存配置并在进程存在时恢复它。这会导致 read 运行时所做的修改被丢弃。解决方案是在运行 read 之前恢复默认值,并在 read 完成后重做。

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 也noted 那个

使用 old=$(stty -g) 捕获当前终端设置,然后使用 stty "$old" 恢复这些设置会很有用。

Explaination

使用它可以让您在调用 stty -g 时恢复确切的终端设置。这比使用 stty -echo 等撤消更改更可靠。

我认为这是更合适的解决方案,因为默认情况下 stty 可能会以无回声模式运行。