使用变量存储 PS1 的终端颜色代码?

使用变量存储 PS1 的终端颜色代码?

在我的 中.bashrc,我使用 ANSI 终端颜色代码来为各个位着色。它看起来像这样:

PS1='\u@\h:\w\[\033[33m\]$(virtual_env)\[\033[32m\]$(git_branch)\[\033[0m\]$ '

其中virtual_envgit_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(andYELLOWRESET) 中,但更好的选择是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}$ '

相关内容