解决方案

解决方案

所以这是我的交易:在 BASH 中工作,我已经构建了一个可以正常工作的函数,它接受一个数组或任意数量的参数,并吐出一个交互式菜单,可以通过向上或向下箭头导航,并以用户点击结束输入,突出显示他们想要的菜单项(其输出是索引或菜单项的值,具体取决于菜单的启动方式):

菜单方法的输出示例

一切正常;我渲染菜单,然后响应从用户输入解析到命令的不可见提示的事件read(在收集 3 个字符后自动触发): read -s -n 3 key 2>/dev/null >&2 输出被输入到$key变量中,然后通过一条case评估语句运行针对预测的可接受的输入:( \033[A向上) \033[A(向下) ""(输入),这反过来会激发所需的行为。

然而,我随后意识到,随着 7 个以上菜单项的引入(我们可能预设不会超过 10 个),让用户点击所需菜单项的数字条目会很好,这会突出显示该项目有问题无需提交

我的问题是这样的: 我的工作也很好,但是用户输入了所需的数字键(在本例中为 5),然后必须按下enter该语句的键read来触发其效果,这要归功于-n 3我的read.这与已经建立的可用性模型背道而驰,当然,除非他们三次点击数字选择,从而触发 3 个字符的最低要求(这同样违反直觉)。

问题\033[A视为 3 个字符,因此需要-n 3. 0-9 被视为单个字符(这意味着如果我将其更改为 a -n 1,它们的行为将按预期进行,但现在箭头键失败,仅收集转义字符)。

所以,我想我想知道的是:有没有办法听 a -n 1 {OR} 3 (whichever comes first)我似乎无法发送\n\r类似的信息,因为在问题read解决之前,它们没有任何效果(这意味着我没有找到任何方法可以-n 3在运行并行进程时简单地离开 来检查输入的值是否为 0-9(如果证明)单个字符)。

我不喜欢这种方法。我可以使用awkor sed,甚至expect(尽管最后一个我仍然感到困惑)。我不在乎它是否read负责收集。

编辑:

解决方案

read -n1 c
case "$c" in
    (1) echo One. ;;
    (2) echo Two. ;;
    ($'\033') 
        read -t.001 -n2 r
        case "$r" in
            ('[A') echo Up. ;;
            ('[B') echo Down. ;;
        esac
esac

状态:已解决

@choroba 来救援!

解决方案说明

我会尽力解释一下:

他的解决方案涉及筑巢这两个read语句(我一直在按顺序尝试它们)正是这个,加上-t.001(从而在函数上设置近乎即时的超时)启用了结转读取。

我的问题是我一直在监视的转义键的长度是 3 个字符(因此我设置了标志-n3)。直到事后我才意识到,接受某些事实单身的- 字符输入也将是有利的。

他的解决方案是提出一个**($'\033')案例:

基本上

  1. '读取转义字符后...' ( **($'\033'))
  2. Create anotherread``(这次等待两个字符),并设置为纳秒后超时并排除转义字符上的反斜杠。

由于行为read显然是将剩余的输入“溢出”到下一个 read声明,该声明开始倒计时,所寻求的值已经被播种。由于满足了定义的要求标志read,因此测试第二组字符的情况结果就变成了一个简单的事情(并且由于初始化函数仍然得到其期望的响应,尽管来自不同的语句,因此程序携带就好像它已经得到了我一开始一直想弄明白的结果。

答案1

您可以阅读 for -n 1,如果第一个是,请阅读以下两个\033并做出相应的反应。否则直接处理号码。

#!/bin/bash

read -n1 c
case "$c" in
    (1) echo One. ;;
    (2) echo Two. ;;
    ($'\033') 
        read -t.001 -n2 r
        case "$r" in
            ('[A') echo Up. ;;
            ('[B') echo Down. ;;
        esac
esac

相关内容