bash 脚本 - 读取单个击键,包括特殊键 Enter 和 Space

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22842896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:06:40  来源:igfitidea点击:

bash scripting - read single keystroke including special keys enter and space

linuxbashshellspecial-characterskeystroke

提问by a.peganz

Not sure if I should put this on stackoverflow or unix.stackexchange but I found some similarquestionshere, so here it goes.

不确定我是否应该把它放在 stackoverflow 或 unix.stackexchange 上,但我在这里发现了一些类似的问题,所以就在这里。

I'm trying to create a script to be called by .bashrc that allows me to select one of two options based on a single keystroke. That wouldn't be hard normally but I want the two keys corresponding to the two options to be space and enter.

我正在尝试创建一个由 .bashrc 调用的脚本,它允许我根据一次击键选择两个选项之一。这通常不会很难,但我希望与两个选项相对应的两个键是空格和输入。

Here's what I got so far:

这是我到目前为止所得到的:

#!/bin/bash

SELECT=""
while [[ "$SELECT" != $'\x0a' && "$SELECT" != $'\x20' ]]; do
    echo "Select session type:"
    echo "Press <Enter> to do foo"
    echo "Press <Space> to do bar"
    read -s -N 1 SELECT
    echo "Debug/$SELECT/${#SELECT}"
    [[ "$SELECT" == $'\x0a' ]] && echo "enter" # do foo
    [[ "$SELECT" == $'\x20' ]] && echo "space" # do bar
done

The following output is what I get if I press enter, space, backspace and x:

如果我按回车、空格、退格和 x,我会得到以下输出:

:~$ bin/sessionSelect.sh
Select session type:
Press <Enter> to start/resume a screen session
Press <Space> for a regular ssh session
Debug//0
Select session type:
Press <Enter> to start/resume a screen session
Press <Space> for a regular ssh session
Debug//0
Select session type:
Press <Enter> to start/resume a screen session
Press <Space> for a regular ssh session
Debug//1
Select session type:
Press <Enter> to start/resume a screen session
Press <Space> for a regular ssh session
Debug/x/1

So both enter and space result in an empty SELECT. No way to distinguish the two. I tried to add -d 'D' to the read options, but that didn't help. Maybe someone can point me in the right direction.

所以 enter 和 space 都会导致一个空的 SELECT。没有办法区分这两者。我试图将 -d 'D' 添加到读取选项中,但这没有帮助。也许有人可以指出我正确的方向。

The bash version would be 4.2 btw.

bash 版本是 4.2 btw。

采纳答案by Cole Tierney

Try setting the read delimiter to an empty string then check the builtin $REPLY variable:

尝试将读取分隔符设置为空字符串,然后检查内置的 $REPLY 变量:

read -d'' -s -n1

For some reason I couldn't get it to work specifying a variable.

出于某种原因,我无法让它在指定变量时工作。

回答by Andrey

#!/bin/bash
SELECT=""
# prevent parsing of the input line
IFS=''
while [[ "$SELECT" != $'\x0a' && "$SELECT" != $'\x20' ]]; do
  echo "Select session type:"
  echo "Press <Enter> to do foo"
  echo "Press <Space> to do bar"
  read -s -N 1 SELECT
  echo "Debug/$SELECT/${#SELECT}"
  [[ "$SELECT" == $'\x0a' ]] && echo "enter" # do foo
  [[ "$SELECT" == $'\x20' ]] && echo "space" # do bar
done

回答by devnull

There are a couple of things about readthat are relevant here:

这里有几件事与read此相关:

  • It reads a single line
  • The line is split into fields as with word splitting
  • 它读取一行
  • 与分词一样,该行被拆分为字段

Since you're reading one character, it implies that entering Enterwould result into an empty variable.

由于您正在阅读一个字符,这意味着输入Enter将导致一个空变量。

Moreover, by default rules for word splitting, entering Spacewould also result into an empty variable. The good news is that you could handle this part by setting IFS.

此外,在默认的分词规则下,输入Space也会导致一个空变量。好消息是您可以通过设置IFS.

Change your readstatement to:

将您的read声明更改为:

IFS= read -s -n 1 SELECT

and expect a null string instead of $'\x0a'when entering Enter.

并期望一个空字符串而不是$'\x0a'输入时Enter