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