为什么我的函数在PS1中没有重新评估?

我试图通过一个函数动态设置我的提示符的一部分,所以在我的.bashrc文件中有以下内容:
asdf ()
{
    echo -n $(pwd)
}
PS1="\u@\h:\w $(asdf)\$ "

打开一个shell,一开始给我了我所期望的东西:
$ bash
darthbith@server:~/test /home/darthbith/test$

然而,当我改变目录时,函数定义的部分并不会改变。
darthbith@server:~/test /home/darthbith/test$ cd ~/test2
darthbith@server:~/test2 /home/darthbith/test$

我的实际目标是在使用git-prompt.sh脚本时,在我所在的git仓库中以漂亮的颜色和其他一切显示分支,但问题是当我切换仓库时,它从未更新分支名称。上面的简单示例是我为了提问而想出的最简单的复现方式。
我需要将git-prompt脚本整合到.bashrc文件中的这些行:
source ~/.git-prompt.sh
PS1="\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(__git_ps1)\$ "

在另一方面,如果你想要一个Git提示符,我推荐 https://github.com/magicmonty/bash-git-prompt/blob/master/README.md - mgor
2个回答

根据Bash提示符使用指南
[21:58:33][giles@nikola:~]$ PS1="[\$(date +%H%M)][\u@\h:\w]\$ "
[2159][giles@nikola:~]$ ls
bin   mail
[2200][giles@nikola:~]$

It's important to notice the backslash before the dollar sign of the command substitution. Without it, the external command is executed exactly once: when the PS1 string is read into the environment.


谢谢!现在只要我能让它打印颜色而不是从函数返回的转义序列就好了... - darthbith

当你在双引号中使用$(..)时,shell会在赋值给PS1之前评估命令替换。因此,PS1只包含输出,而不是命令替换本身。相反,要么使用单引号,要么转义$,这样字符串将按原样传递给PS1,然后在设置提示符时进行评估:
$ PS1='$(pwd) $ '
/tmp $ cd /var
/var $ echo "$PS1"
$(pwd) $ 

比较:
/var $ PS1="$(pwd) $ "
/var $ echo "$PS1"
a /var $  a
/var $