所以这是我的交易:在 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(如果证明)单个字符)。
我不喜欢这种方法。我可以使用awk
or 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')
案例:
基本上
- '读取转义字符后...' (
**($'\033')
) Create another
read``(这次等待两个字符),并设置为纳秒后超时并排除转义字符上的反斜杠。
由于行为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