Bash 提示变量在 bash 函数中不起作用

Bash prompt variables does not work inside a bash function

我正在进行快速自定义,但出于某种原因,当我使用 \u\h\W 变量时,它工作得很好,但是当我将它们放在一个函数中,它们将显示为“\u”或“\W”而不是它们的值。

...

print_user()
{
  echo -e "[=12=]1\u[=12=]2@[=12=]1\h[=12=]2"
}

print_dir()
{
  echo -e "[=12=]1${YELLOW}[=12=]2[=12=]1\W[=12=]2[=12=]1${RESET_ATTR}[=12=]2"
}

PS1='[$(print_user) on $(print_dir)] $(get_git_repo) [=12=]1\n[=12=]2$(print_prompt) '

这显示为:

[\u@\h on \W]
>

如果我像这样将它们移到函数之外

PS1='[\[\u\]@\[\h\] \[${YELLOW}\]\[\w\]\[${RESET_ATTR}\]] $(get_git_repo) \[\n\]$(print_prompt)'

它工作正常,并显示带有用户名和主机名的当前目录:

[myusername@arch on ~]
>

这就是 bash 的工作方式吗?有没有不同的方法可以做到这一点?为什么在函数内部不显示变量值,而在函数外部却显示变量值?

来自手册页,在 PROMPTING

Bash allows these prompt strings to be customized by inserting a number of backslash-escaped special characters that are decoded as follows:

[...]

After the string is decoded, it is expanded via parameter expansion, command substitution, arithmetic expansion, and quote removal, subject to the value of the promptvars shell option (see the description of the shopt command under SHELL BUILTIN COMMANDS below).

当 shell 扩展 $(print_user) 以将 \u 添加到字符串时,解码它已经来不及了,因此文字字符串 \u 保留在提示。

一种替代方法是使用 PROMPT_COMMAND 来执行动态定义 PS1 的函数,就在它显示之前,而不是在 PS1 本身的值中嵌入命令替换。

make_prompt () {
  PS1="[$(print_user) on $(print_dir)] $(get_git_repo)"
  PS1+='\[\n\]'
  PS1+="$(print_prompt) "
}

PROMPT_COMMAND=make_prompt

现在,print_user 将在 之前被调用 shell 解码 PS1 的值,届时所有提示都会转义将出席。