Ism*_*awi 33 bash prompt terminal environment-variables
在我的.bashrc. 它看起来像这样:
PS1='\u@\h:\w\[\033[33m\]$(virtual_env)\[\033[32m\]$(git_branch)\[\033[0m\]$ '
Run Code Online (Sandbox Code Playgroud)
其中virtual_env和git_branch是在标准输出上输出内容的 bash 函数。
现在,为了更易于阅读和修改,我想将颜色代码存储在变量中并引用它们,而不是将它们直接嵌入到PS1. 所以我有一堆这样的变量:
GREEN="\[\033[32m\]"
YELLOW="\[\033[33m\]"
RESET="\[\033[0m\]"
Run Code Online (Sandbox Code Playgroud)
我希望能够写出类似的东西:
PS1='\u@\h:\w${YELLOW}$(virtual_env)${GREEN}$(git_branch)${RESET}$ '
Run Code Online (Sandbox Code Playgroud)
但这不起作用——颜色代码显示在提示中,就像它们被转义一样。如果我使用双引号代替 for PS1,颜色可以正常工作,但只有在我这样做时提示才会改变source ~/.bashrc。
我尝试了其他我见过的人做的事情——使用printf,使用单引号作为颜色,将\[和\]放入PS1而不是颜色变量,但似乎没有任何效果。
如何为颜色代码使用变量?
phe*_*mer 20
解决方案是让 shell 在定义提示时替换颜色变量,而不是函数。为此,请使用您最初尝试的双引号,但对命令进行转义,以便在绘制提示之前不会对它们进行评估。
PS1="\u@\h:\w${YELLOW}\$(virtual_env)${GREEN}\$(git_branch)${RESET}$ "
Run Code Online (Sandbox Code Playgroud)
注意每个命令上的\之前$()。
如果我们回应这一点,我们会看到:
echo "$PS1"
\u@\h:\w\[\033[33m\]$(virtual_env)\[\033[32m\]$(git_branch)\[\033[0m\]$
Run Code Online (Sandbox Code Playgroud)
如您所见,颜色变量被替换,但命令没有被替换。
问题是您的变量GREEN包含由“反斜杠括号反斜杠零三三”等组成的文字字符串。它不包含例如让您的终端改变颜色所需的 ASCII 转义字符。
您可以手动将控制字符放入GREEN(andYELLOW和RESET) 中,但更好的选择是首先使用tput,这样您就不需要硬编码任何内容并且您将支持任何终端类型。
GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"
RESET="$(tput setaf 0)"
Run Code Online (Sandbox Code Playgroud)
将“反斜杠零三三”等直接放入其中的原因PS1是某些反斜杠序列的解释是bash提示的功能(请参阅手册中的提示部分。此替换发生在参数扩展,命令之前但是,替换、算术扩展和引号删除,因此它不适用于所有其他操作的结果。