unix 读取命令:以彩色显示提示(或启用反斜杠转义的解释)

sirbozc5  于 2023-01-25  发布在  Unix
关注(0)|答案(6)|浏览(143)

我经常使用类似read -e -p "> All good ? (y/n)" -n 1 confirm;的命令来请求用户确认。
我正在寻找一种方法来着色输出,如命令echo -e所做的:

echo -e "\033[31m";
echo "Foobar";       // will be displayed in red
echo -e "\033[00m";

我使用的是xterm。
man echo中,它表示:
-e启用反斜杠转义的解释
有没有办法用read命令做同样的事情?(手册页中没有:(-r选项不起作用)

6qqygrtg

6qqygrtg1#

read不会处理-p的参数中的任何特殊转义,因此您需要按字面意思指定它们。bash的ANSI引号字符串对此非常有用:

read -p $'\e[31mFoobar\e[0m: ' foo

您还应该能够使用Control-vEscape键入一个文本转义字符,它将在终端中显示为^[

read -p '^[[31mFoobar^[[0m: ' foo
iqxoj9l9

iqxoj9l92#

这里有另一个解决方案,允许使用变量来更改文本的格式。echo -e将所需的输出转换为read命令的-p参数。
示例:

RESET="\033[0m"
BOLD="\033[1m"
YELLOW="\033[38;5;11m"
read -p "$(echo -e $BOLD$YELLOW"foo bar "$RESET)" INPUT_VARIABLE
vcirk6k6

vcirk6k63#

将查询分为两个部分:
1.使用echo-e-n显示提示符
1.使用read收集用户响应
例如:

echo -e -n "\e[0;31mAll good (y/n)? "   # Display prompt in red
echo -e -n '\e[0;0m'                    # Turn off coloured output
read                                    # Collect the user input

echo *-n * 选项禁止尾随换行符。

hzbexzde

hzbexzde4#

我的工作:

BC=$'\e[4m'
    EC=$'\e[0m'

    while true; do
            read -p "Do you wish to copy table from ${BC}$HOST $PORT${EC} to ${BC}$LOCAL_HOST $LOCAL_PORT${EC}? (y or n)" yn
        case $yn in
        ....
    done

结果如下:

更多示例,请参见展示案例,链接为:
mysqlis

bttbmeg0

bttbmeg05#

注意,这里的答案是正确的给出的问题,即限制读取字符的数量为1(-n 1),只要一个人想读更多(即读一行)这里的答案不完全正确)。

read -e -p "> All good ? (y/n)" -n 1

即只读取1个字符(-n 1),此处的答案正确。
如果一个人带着一个类似的问题来到这里,但是输入更长(no-n1),那么所有的答案都是错误的,因为长输入会被readline在行换行点处搞砸。
如以下答复所述:

P="\e[31mPrompt\e[m" ; read -e -p "$P" b

不如bash readline好,不解释\e字符,它只是"按原样"显示它们
但是:

P=$'\e[31mPrompt\e[m' ; read -e -p "$P" b

更好,因为二进制字符串由readline显示,但提示长度比可见长度(esc序列)长7个字符,然后使readline在长输入行上扭曲换行,错误地呈现对长行的编辑。
我找到了一种方法来欺骗readline,让prompt带有属性,同时还能处理长输入,其思想是用echo发出prompt(正如一些人所建议的),它将遵循esc序列属性,然后使用具有提示字符串可视长度的提示符执行readline(PromptLen-escSeqLen),但实际上什么也不显示,这样readline会发出长度正确的NOP提示,然后正确处理长线。我想到了这个。

P="Prompt :"
echo -ne "\e[31m$P\e[m" ; read -e -p "${P//?/$'\a'}" b
echo "b='$b'"

这是可行的,正确地处理了长换行,现在的缺点是"可能是"一个恼人的贝尔字符,但大多数终端尊重DECSMBV转义序列来关闭它。

dm7nw8vv

dm7nw8vv6#

read -ep中使用终止转义序列的问题是,它会打乱提示机制对换行的处理,因为它对提示符字符宽度的假设最终会错误地计算颜色代码。
解决方案是使用特殊的转义序列\001\002(否则knownRL_PROMPT_START_IGNORERL_PROMPT_END_IGNORE)来排除非打印字符的计数,如this示例所示。
例如:

_YELLOW=$'\001\e[33m\002'
_RESET=$'\001\e[m\002'

read -erp "$_YELLOWprompt>$_RESET " input
echo
echo "Your input: $input"

下面是一个工作实现。

相关问题