我正在尝试在终端的提示符下添加分支名称,例如user@host:directory [branch]
。我尝试了两个代码,发现Code.2无法正常工作。签出另一个分支时不反映分支名称。看来bash正在缓存上一个命令的结果。
有人可以告诉我Code.2的问题是什么吗?我还想知道\
之前的$()
是什么意思?
user@host:directory [master]$ cat ~/.bashrc
PS1="\u@\h:\W \$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/[\1]/')\$ "
user@host:directory [master]$ git checkout another-branch
user@host:directory [another-branch]$
user@host:directory [another-branch]$ git checkout master
user@host:directory [master]$
user@host:directory [master]$ cat ~/.bashrc
BRANCH_NAME=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/[\1]/')
PS1="\u@\h:\W ${BRANCH_NAME}\$ "
user@host:directory [master]$ git checkout another-branch
user@host:directory [master]$
user@host:directory [master]$ git checkout master
user@host:directory [master]$
答案 0 :(得分:2)
这确实与Git无关-纯粹是在bash本身中执行所需操作的问题。
Bash有五个名为described in the documentation的变量,分别名为PS0
,PS1
,PS2
,PS3
和PS4
:>
PS0 该参数的值像
PS1
一样展开,并在读取命令之后和执行命令之前由交互式shell显示。PS1 主提示字符串。默认值为
‘\s-\v\$ ’
。有关在显示PS1
之前展开的转义序列的完整列表,请参见Controlling the Prompt。PS2 次要提示字符串。默认值为
‘> ’
。在显示之前,PS2
的扩展方式与PS1
相同。PS3 该变量的值用作
提示select
命令的提示。如果未设置此变量,则选择命令将以‘#? ’
PS4 设置
PS1
后,此参数的值将像-x
一样展开,并且展开的值是在回显命令行之前打印的提示(请参见The Set Builtin)。必要时,将扩展值的第一个字符复制多次,以指示多个间接级别。默认值为‘+ ’
。
这里最棘手的部分是PS1
在通过扩展提示进行评估之前,会通过扩展进行评估。此评估具有许多不可思议的转义序列,所有这些都在linked section about controlling the prompt中进行了描述。然后,如文档所述:
对字符串进行解码后,可以根据参数
promptvars
shell选项的值(请参阅The Shopt Builtin)通过参数扩展,命令替换,算术扩展和引号删除来扩展它。
命令替换部分在有效的设置(第一个.bashrc
,您称为Code.1)中很重要。该bashrc部分读取:
PS1="\u@\h:\W \$(git branch)\$ "
(为了简化说明,我将其缩短了很多内容)。当bash来源此bashrc时,将对这一行进行一次评估,因此,双引号内的每个元素此时都必须进行参数扩展,命令替换,算术扩展和引号删除 。所有这些的结果是将PS1
设置为:
\u@\h:\W $(git branch)$
(上面一行的末尾有一个空格)。
现在bash每次要打印提示时,都会再次评估PS1 。此 second (但重复进行)评估对\u
,\H
和\W
进行解码,使shell保留:
user@host:directory $(git branch) $
此序列现在进行
再次参数扩展,命令替换,算术扩展和引号删除
和这次,$(git branch)
产生命令替换结果。 (这将显示为master
或another-branch
,不带方括号;我放下的sed
会解决这些问题。)
bashrc的“ Code.2”版本部分读取:
PS1="\u@\h:\W ${BRANCH_NAME}\$ "
在读取该bashrc本身时会经历一次常规规则,而留下来:
\u@\h:\W [master]$
(再次在末尾有一个空格)作为存储在PS1
中的值。在读取每个命令之前,将再次对该值进行“解码[并]扩展”,但是这次没有命令可作为命令替换的一部分运行。文字[master]
嵌入值中。