我在使用已知的生成用户输入提示的方法时遇到问题:
read -p "Input something: " variabile
如果尝试使用箭头键,这会导致问题,它会为每个箭头键行程回显 ANSI 代码
read -e -p "Input something: " variable
这修复了箭头键问题,但是当达到终端的宽度时,文本输入不会在换行符上继续,而是在同一行上,覆盖(视觉上)现有输入
echo -n "Input something: "; read -e variable
这显然解决了之前描述的两个问题......直到我发现输入内容然后按退格键会覆盖提示,并且当输入较长时,从输入的第二个换行符开始,视觉覆盖再次出现。
那么有没有一种好的提示方式可以避免上述问题呢?
更新
重新检查后,我现在知道是什么导致了 read -e -p
的输入覆盖
我正在使用这些变量来突出显示阅读提示的文本:
highlight=$(echo -e "\e[1;97m")
clear=$(echo -e "\e[0m")
read -e -p "Input$highlight something$clear: " variable
这是我可以在 read
提示中使突出显示工作的唯一方法(将转义序列分配给变量不起作用,我需要像我一样回应它们)但它们似乎也导致输入覆盖问题。
最佳答案
正如 dimo414 提到的,readline 认为提示比实际的要长。它在计算长度时计算终端转义序列中的每个字符。可以看到它认为转义序列有多长如下
echo ${#highlight}
在 bash PS1 提示符中,用 "\["
和 "\]"
包围这样的转义序列指示 readline 在计算当前行长度时忽略之间的所有内容,但这些不是内置 bash read
的正确转义符。
read
的转义是$'\001'
和$'\002'
,如BashFAQ 中所述,但根据我的经验,您还需要在 read
上使用 -e
选项。做你想做的事的蛮力方式是:
read -e -p "Input "$'\001'"${highlight}"$'\002'something$'\001'"${clear}"$'\002'": "
为了终端独立性,您应该使用 tput 而不是硬编码的转义序列。阅读 man 5 termcap
。
参见 my dotfiles为优雅的 bash 函数做上面的开始/结束引用。
关于Bash 脚本用户输入提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34797910/