我在生成用户输入提示的已知方法时遇到问题:
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
的转义是 $' 01'
和$' 02'
,如 BashFAQ 中所述,但根据我的经验,您还需要 read
上的-e
选项。执行您想要的操作的蛮力方法是:
read -e -p "Input "$' 01'"${highlight}"$' 02'something$' 01'"${clear}"$' 02'": "
为了终端独立性,您应该使用 tput 而不是硬编码的转义序列。阅读man 5 termcap
.
请参阅我的点文件以获取优雅的 bash 函数,为您完成上面的开始/结束引用。
shell 会跟踪它认为提示的时间,以便知道用户的输入在哪里开始和停止。不幸的是,当您在提示中打印彩色转义码时,您会抛出 Bash 的计数,因为它期望转义字符占用终端中的空间。
为了避免这种情况,您只需将所有颜色序列包装在 [
和 ]
中,这会告诉您的 shell 包含的字符是非打印的,不应计算在内。
例如,highlight
变量应为:
highlight=$(echo -e "[e[1;97m]")
就个人而言,我使用我的 Prompt.gem 项目中的 color
和 pcolor
函数,它处理正确的转义并使您的命令更易于阅读:
read -e -p "Input $(pcolor DEFAULT BOLD)something$(pcolor): " variable