Bash:检测按键:如何读取特殊的十六进制键序列(如插入)以及为什么它是“\x1b\x5b\x32\x7e”(插入)?

Bash: detecting key-presses: how to read special key hex sequence(like Insert) and why it is '\x1b\x5b\x32\x7e'(Insert)?

在 Advanced Bash-Scripting Guide Section 5.2 Example 5-3. Detecting key-presses. The whole code can be viewed at detecting_key-presses.sh 一书中。在示例中,有一些我无法理解的代码片段。

第一个片段:

# Convert the separate home-key to home-key_num_7:
if [ "$key" = $'\x1b\x4f\x48' ]; then
    key=$'\x1b\x5b\x31\x7e'
    #   Quoted string-expansion construct.
fi

# Convert the separate end-key to end-key_num_1.
if [ "$key" = $'\x1b\x4f\x46' ]; then
    key=$'\x1b\x5b\x34\x7e'
fi

$'\x1b\x5b\x32\x7e')  # Insert
    echo Insert Key
    ;;

在上面的片段中,例如,当我按下 Home 键和 Insert 键时,

  1. 为什么它会为 Home 生成 \x1b\x4f\x48 个序列,为 Insert 生成 \x1b\x5b\x32\x7e 个序列?
  2. 而且评论说"Convert the separate home-key to home-key_num_7"和"Convert the separate end-key to end-key_num_1",转换,"key_num_7"和"key_num_1"是什么意思?

第二个片段:

unset K1 K2 K3
read -s -N1 -p "Press a key: "
K1="$REPLY"
read -s -N2 -t 0.001
K2="$REPLY"
read -s -N1 -t 0.001
K3="$REPLY"
key="$K1$K2$K3"

在上面的片段中,每次我按下一个键,

  1. 为什么要读取3个变量来构造一个关键的十六进制序列?
  2. 第二个read -s -N2 -t 0.001,为什么要指定-t(超时)选项和-N2(nchars)读取2个字符而不是1个?

问了几个问题...

脚本需要 转义序列 通过 特殊键 发送。在典型的键盘上,这些是所有具有名称或图形符号的键(例如 ←,表示左光标)。根据约定(没有适用的标准)这些键发送以escape[=开头的字符序列48=],第二个字符通常是 [。对于这两个字符,十六进制代码分别为 0x1b0x5b(参见 ASCII table). The 0x4f is the letter O, and would be sent by a terminal's special keys in application mode .

您的 HomeEnd[ 发送的特定序列=53=] 键使用与其他一些特殊键略有不同的约定,称为 PC 风格 (请参阅 xterm FAQ Why can't I use the home/end keys? 作为背景)。显然,脚本的开发者决定通过确保 Home 和 [=42] 发送的序列的两个变体来解决与该 FAQ 相关的问题=]End 将被翻译成 VT220-style 序列。

最后一个问题问为什么要分开读取,使用分开的变量。这是因为由特殊密钥发送的字符序列可能会通过网络传输,并且比 read 操作所允许的时间更长。因此每次尝试只能读取序列的一部分。脚本收集片段并将它们组合成一个字符序列。