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

时间:2021-03-27 00:05:42

In the book Advanced Bash-Scripting Guide Section 5.2 Example 5-3. Detecting key-presses. The whole code can be viewed at detecting_key-presses.sh. In the example, there is some code snippet which I can't understand.

在《高级bash脚本指导》一书中,5.2节示例5-3。检测按键。整个代码可以在detecting_key-press .sh中查看。在这个示例中,有一些代码片段我无法理解。

First snippets:

第一个片段:

# 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
    ;;

In the above snippet, for example, when I press Home key and Insert key,

在上面的代码片段中,例如,当我按Home键和插入键时,

  1. Why it will produce \x1b\x4f\x48 sequences for Home and \x1b\x5b\x32\x7e sequences for Insert?
  2. 为什么它会产生家庭用的\x1b\x4f\x48序列和插入用的\x5b\x32\x7e序列?
  3. And the comment says that "Convert the separate home-key to home-key_num_7" and "Convert the separate end-key to end-key_num_1", what does the conversion, "key_num_7" and "key_num_1" means?
  4. 注释说“将独立的home键转换为home-key_num_7”,“将独立的end-key转换为end-key_num_1”,“key_num_7”和“key_num_1”是什么意思?

Second snippet:

第二个片段:

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"

In the above snippet, every time I pressed one key,

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

  1. Why it read 3 variable to construct a key hex sequences?
  2. 为什么它读3个变量来构造一个关键的十六进制序列?
  3. The second read -s -N2 -t 0.001, why should specify the -t(timeout) option and -N2(nchars) to read 2 characters not 1?
  4. 第二个读取-s -N2 -t 0.001,为什么要指定-t(timeout)选项和-N2(nchars)来读取两个字符,而不是一个字符?

1 个解决方案

#1


1  

There are several questions asked...

有几个问题……

The script is expecting escape sequences to be sent by special keys. On a typical keyboard, those are all of the keys which have a name or graphic symbol (such as ←, for left-cursor). By convention (there is no applicable standard) those keys send sequences of characters beginning with escape, with the second character often [. For just those two characters, the hexadecimal codes are 0x1b and 0x5b, respectively (see ASCII table). The 0x4f is the letter O, and would be sent by a terminal's special keys in application mode.

脚本期望通过特殊的键发送转义序列。在一个典型的键盘,这些都是有一个名称或图形符号的键(←left-cursor)等。按照约定(没有适用的标准),这些键发送以转义开头的字符序列,通常是第二个字符[。对于这两个字符,十六进制代码分别是0x1b和0x5b(参见ASCII表)。0x4f是字母O,在应用模式下由终端的特殊键发送。

The particular sequences sent by your Home and End keys use a slightly different convention from some of the other special keys, referred to a PC-style (see the xterm FAQ Why can't I use the home/end keys? for the background on that). Apparently the developer of the script decided to solve a problem related to that FAQ by ensuring that both variations of the sequences sent by Home and End would be translated into the VT220-style sequence.

你的Home键和End键发送的特定序列使用了与其他一些特殊键稍有不同的约定,即pc风格(参见xterm FAQ常见问题解答为什么我不能使用Home / End键?)作为背景)。显然,脚本的开发人员决定通过确保Home和End发送的序列的两个变体都被翻译成vt220样式的序列来解决与FAQ相关的问题。

The last question asks why it is necessary to do separate reads and use separate variables. That is because the sequence of characters sent by a special key may be transmitted over a network, and take more time than one of those read operations allows. So only part of the sequence may be read at each try. The script collects the pieces and puts them together as one sequence of characters.

最后一个问题是为什么需要进行单独的读取和使用单独的变量。这是因为一个特殊的密钥发送的字符序列可能通过网络传输,并且花费的时间比读操作允许的时间长。所以每次尝试只能读取序列的一部分。脚本收集这些片段并将它们作为一个字符序列放在一起。

#1


1  

There are several questions asked...

有几个问题……

The script is expecting escape sequences to be sent by special keys. On a typical keyboard, those are all of the keys which have a name or graphic symbol (such as ←, for left-cursor). By convention (there is no applicable standard) those keys send sequences of characters beginning with escape, with the second character often [. For just those two characters, the hexadecimal codes are 0x1b and 0x5b, respectively (see ASCII table). The 0x4f is the letter O, and would be sent by a terminal's special keys in application mode.

脚本期望通过特殊的键发送转义序列。在一个典型的键盘,这些都是有一个名称或图形符号的键(←left-cursor)等。按照约定(没有适用的标准),这些键发送以转义开头的字符序列,通常是第二个字符[。对于这两个字符,十六进制代码分别是0x1b和0x5b(参见ASCII表)。0x4f是字母O,在应用模式下由终端的特殊键发送。

The particular sequences sent by your Home and End keys use a slightly different convention from some of the other special keys, referred to a PC-style (see the xterm FAQ Why can't I use the home/end keys? for the background on that). Apparently the developer of the script decided to solve a problem related to that FAQ by ensuring that both variations of the sequences sent by Home and End would be translated into the VT220-style sequence.

你的Home键和End键发送的特定序列使用了与其他一些特殊键稍有不同的约定,即pc风格(参见xterm FAQ常见问题解答为什么我不能使用Home / End键?)作为背景)。显然,脚本的开发人员决定通过确保Home和End发送的序列的两个变体都被翻译成vt220样式的序列来解决与FAQ相关的问题。

The last question asks why it is necessary to do separate reads and use separate variables. That is because the sequence of characters sent by a special key may be transmitted over a network, and take more time than one of those read operations allows. So only part of the sequence may be read at each try. The script collects the pieces and puts them together as one sequence of characters.

最后一个问题是为什么需要进行单独的读取和使用单独的变量。这是因为一个特殊的密钥发送的字符序列可能通过网络传输,并且花费的时间比读操作允许的时间长。所以每次尝试只能读取序列的一部分。脚本收集这些片段并将它们作为一个字符序列放在一起。