我不擅长 bash 和 Linux。我正在阅读一个脚本,我发现了以下函数。
get_char()
{
SAVEDSTTY=`stty -g`
stty -echo
stty cbreak
dd if=/dev/tty bs=1 count=1 2> /dev/null
stty -raw
stty echo
stty $SAVEDSTTY
}
基本上,它用于实现这样的按任意键继续功能。
echo "Press any key to continue!"
char=`get_char`
我知道您可以使用内置read
命令来实现这一点。例如:
read -rsn1 -p "Press any key to continue"
有什么理由使用这个函数而不是内置read
命令?
问题中的
get_char
函数有问题 wrt 生成多字节字符的键,并且stty
作用于标准输入但从[1]dd
读取的事实/dev/tty
,所以我将使用它的“固定”和简化版本进行比较:k=$(get_char)
和之间的一些区别read -rsn1 k
是:前者是便携式的;它在
dash
,bash
,zsh
等中的工作方式相同。read -rsn1
仅在bash
和中有效ksh
。当按下 like
F1
键时,k=$(get_char)
将设置为由键 ( )k
生成的整个转义,而不是吃掉前导(Esc) 并留待以后使用。这同样适用于生成多个字符的任何键。F1
^[OP
^[
OP
Ctrl-C
(VINTR
)、Ctrl-Q
(VQUIT
) 或Ctrl-Z
(VSUSP
) 将导致k=$(get_char)
设置k
为原始控制字符 (\x03
或\x11
)\x1a
,而在使用时会中断或暂停脚本read -rsn1
[2]。[1] 如果它应该从控制 tty 中读取,那么使用它很简单
k=$(get_char </dev/tty)
[2]如果脚本用 暂停然后用 恢复,
read -rsn1
将无法恢复 tty 设置。Ctrl-Z
fg
从带有 line-editor 的 shell 使用时的示例——它本身会弄乱 tty 设置:
或者当从不与 tty 设置混淆的 shell 中使用时(例如
dash
):