在bash中打印转义的彩色字符

5
我正在使用C语言中的readline库在bash中创建一个类似于bash的提示符。当我尝试使用像这些颜色序列使提示符变得丰富多彩时,颜色正常显示,但光标的间距出现了问题。输入太早被换行,而换行到同一行上,因此开始覆盖提示符。我认为应该使用\[\]转义颜色序列,如下所示: readline("\[\e[1;31m$\e[0m\] ") 但是,这会打印出方括号,如果我转义反斜杠,它也会打印那些字符。我该如何转义颜色代码,使光标仍然起作用?

转义序列这样是Bash特定的事情。如果从程序中打印,您不需要周围的括号。还要注意,序列 "\e" 是GCC编译器中的扩展,它通常不可移植。 - Some programmer dude
为了澄清我的先前评论,我的意思是 "\[""\]" 这一对符号是 Bash 特有的,你不需要它们。 - Some programmer dude
你尝试过使用readline("\[\033[1;31m$\033[0m\] ")吗?请使用\033而不是\e - David Ranieri
2个回答

6

告诉readline在提示字符串中一个字符序列不会在输出到屏幕时实际移动光标的方法是使用标记RL_PROMPT_START_IGNORE(目前,在readline的C头文件中,这是字符文字'\001')和RL_PROMPT_END_IGNORE(当前为'\002')将其包围。

正如@Joachim和@Alter所说,为了可移植性,应该使用'\033'而不是'\e'。


2
我在寻找方法优化bash脚本中GNU readline提示符时发现了这个问题。与C代码中的readline一样,\[\]不是特殊字符,但是 \001\002会被识别并正常工作,只要使用bash引用字符串的形式$'string' ,并将它们明确地写入其中。我之前也遇到过这个问题(由于不知道如何与$'…'组合而未能解决),所以现在提供我的解释,希望能对大家有所帮助。
通过提供的数据,我得出了以下结论:
C1=$'\001\033[1;34m\002'   # blue   -  from \e[1;34m
C0=$'\001\033[0;0m\002'    # reset  -  from \e[0;0m
while read -p "${C1}myshell>$C0 " -e command; do
  echo "you said: $command"
done

这将生成一个蓝色的提示符,显示为myshell>并有一个尾随空格,实际命令没有颜色。 既不会通过按Up键,也不会通过输入换行的命令而混淆非打印字符。
如接受答案中所解释的那样,\001报头开始)和\002文本开始)是RL_PROMPT_START_IGNORERL_PROMPT_END_IGNORE标记,告诉bash和readline不要计算它们之间的任何内容以便对终端进行着色。(还在此处找到:\033\e 更可靠,而且现在我正在使用八进制代码,我也可以再使用一个。)
似乎没有太多关于此的文档; 我能找到的最好的资料是perl的Term::ReadLine::Gnu文档,其中说:

PROMPT可能包含一些转义序列。使用RL_PROMPT_START_IGNORE开始一系列非打印字符,并使用RL_PROMPT_END_IGNORE结束该序列。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接