Jet*_*ohn 8 colors bash terminal escape-characters
最近,我在终端中玩了很多颜色,因此也使用了转义序列。我已经阅读了 Bash 联机帮助页的相关部分以及网络上的许多有用页面。
我已经完成了大部分我想要的工作;例如,漂亮的彩色 Bash 提示。也就是说,我仍然对何时应该使用(或需要使用)“非打印转义序列”字符感到困惑。那些将是\[和\]。
如果我在定义我的提示时没有在 PS1 中使用它们,那么我的提示肯定不会正确显示。如果我确实使用它们,一切都很好。好的。
但是,在 PS1 之外,它们的操作方式似乎不同。例如,为了使脚本更具可读性,我定义了一个$RGB_PURPLE通过简单函数设置的变量c8_rgb()。最终结果是变量包含\[\e[01;38;05;129m\]打开粗体紫色前景色的值。
当我在 PS1 中使用这个变量时,它符合我的预期。如果我通过它使用它printf或者echo -e它“一半”有效。命令printf "${RGB_PURPLE}TEST${COLOR_CLR}\n"(其中COLOR_CLR是重置文本属性的转义序列)导致以下显示:\[\]TEST\[\]除了第一个\[和最后一个以外的所有内容\]都以紫色显示。
为什么会有差异?为什么这些括号被打印出来而不是被终端处理?我希望它们在作为提示的一部分打印时与通过其他方式打印时得到相同的对待。我不明白这种变化。
根据经验,这些字符似乎必须在提示定义中使用,而它们不应该在几乎所有其他情况下使用。这使得使用通用函数(如我c8_rgb()上面提到的函数)来处理转义序列生成和输出变得困难,因为该函数无法知道其结果是在提示配置中还是在其他地方。
和快速的相关问题:是echo -e和printf基本至于输出转义序列相同?我通常使用 printf,但有什么理由偏爱一个而不是另一个?
谁能解释这种明显的细微差别?在终端中使用转义序列(通常仅用于颜色)时,我还应该注意其他什么奇怪的事情吗?谢谢!
在 $PS1 中使用非打印字符时需要“非打印转义序列”,因为 bash 需要知道光标的位置,以便在编辑命令行时可以正确更新屏幕。Bash 通过计算 $PS1 提示符中的字符数然后这是光标所在的列号来做到这一点。
但是,如果您将非打印序列放在 $PS1 中,那么该计数是错误的,并且如果您编辑命令行,该行可能会被弄乱。因此引入\[和\]标记来指示不应计算所包含的字节。
小智 5
我通过在整个过程中使用八进制转义序列以及使用分隔符的 readline 形式找到了一个足够的解决方案。PS1、echo -e 和 printf 都以这种方式使用完全相同的字符串执行正确的操作。我在 OSX 上的 Bash 4 和 Linux 上的 Bash 3 中对此进行了测试。
我从这里的答案中得到了 \001 和 \002 的想法: https: //superuser.com/questions/301353/escape-non-printing-characters-in-a-function-for-a-bash-prompt ?rq =1
例子:
$ TextGreen='\001\033[0;32m\002'
$ TextReset='\001\033[0m\002'
$ SomeString="${TextGreen}prompt_stuph${TextReset} \$ "
$ #
$ # now all of the following work as expected
$ #
$ PS1="$SomeString"
$ printf "$SomeString"
$ echo -e "$SomeString"
Run Code Online (Sandbox Code Playgroud)