为什么我的Bash提示符没有更新?

94

我是Git的新手,我正在尝试将当前的Git分支添加到已经存在的提示符中,该提示符定义如下:

RESET="\[\017\]"
NORMAL="\[\033[0m\]"
RED="\[\033[31;1m\]"
YELLOW="\[\033[33;1m\]"
WHITE="\[\033[37;1m\]"
SMILEY="${WHITE}:)${NORMAL}"
FROWNY="${RED}:(${NORMAL}"
SELECT="if [ \$? = 0 ]; then echo \"${SMILEY}\"; else echo \"${FROWNY}\"; fi"

export PS1="${RESET}${YELLOW}\u@\h${NORMAL} \`${SELECT}\` ${YELLOW}\w $(__git_ps1) >${NORMAL} "
我尝试过重新载入我的.bashrc文件,看起来似乎可以工作,但是当我切换到另一个分支时却没有更新。我该如何确保$(__git_ps1)没有被缓存?

15
我很喜欢这个想法,在提示符中添加 :):( 取决于上一个命令是否失败了 :) - Mark Longair
@Mark Longair:我在这里找到了它:http://serverfault.com/questions/4889/what-are-some-informative-and-useful-shell-prompts-bash-csh-ksh-etc 顺便问一下,你为什么删除了你的解决方案,它也是有效的! - greg0ire
它比另外两个晚了几分钟,而且也不如@geekosaur的整洁。 - Mark Longair
2
非常感谢您提出这个问题(当然,也要感谢geekosaur的回答)!我已经在挣扎了几个小时,试图弄清楚为什么我的提示符只有在我源化我的.bashrc文件时才更新其git状态行。 - coredumperror
2个回答

149

你需要在 $ 前面加上反斜杠,这样它才不会立即被展开。(与 `...` 相比,后者是编写 $(...) 的另一种方式。)

export PS1="${RESET}${YELLOW}\u@\h${NORMAL} \`${SELECT}\` ${YELLOW}\w \$(__git_ps1) >${NORMAL} "

我同意@MikeSep的建议,使用单引号更好,但是让颜色等立即替换会更加优化。这不是必需的,只是有点更好。话虽如此,如果你使用单引号,更容易理解正在发生什么。


2
此外,如果您曾经直接使用终端程序以外的东西(如Emacs/Vim命令缓冲区、screen等),您可能希望考虑使用tput而不是硬编码颜色转义。 - geekosaur
1
在这种情况下,我认为有必要替换颜色变量 - 至少,使用@MikeSep的建议只会得到转义代码,而您的建议可以正常工作。 (+1) - Mark Longair
@Mark:很有趣;${SELECT}这个演示了递归评估正在进行。也许只是针对命令?我通常使用PS1函数,因为更容易弄清楚发生了什么。 - geekosaur
感谢你,@geekosaur。 - smonff
3
你真是个救命恩人。不过我有个问题:我有一台MBP和一台iMac。它们使用相同的.bash_profile文件和相同版本的bash(通过homebrew安装)。在MBP上,如果我在$(__git_ps1)前面不加\,它将不会被评估。但如果我在iMac上做同样的事情,即使没有\,它也会被评估。你知道这是怎么发生的吗? - molli
@molli,您能告诉我们您的MBP和iMac上运行的macOS / OS X版本吗?是相同的吗? - esaruoho

29

你的 PS1 字符串很可能在保存之前已被评估,但你真正想要的是每次获取命令提示符时都运行 __git_ps1 命令。我建议你在你的 export PS1='${RESET}...' 行中使用单引号而不是双引号。


可能会起作用,但我在将整个系统转换为单引号时遇到了问题,所以我会使用geekosaur的解决方案。但你也会得到我的点赞。 - greg0ire
啊,是的。他的更好 - 我错过了颜色的本地变量。无论如何,感谢你的投票。 :) - Mike Seplowitz
使用单引号代替双引号让我省了不少事,谢谢 :) - Banane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接