ZSH setopt PROMPT_SUBST不起作用

5

我正在尝试自定义我的zsh提示符,并且想要每次生成提示符时使用git命令评估一个函数。我正在使用setopt PROMPT_SUBST,但它似乎不起作用。这是我的zshrc文件:

setopt PROMPT_SUBST
autoload -U colors && colors # Enable colors

# Show Git branch/tag, or name-rev if on detached head
parse_git_branch() {
  echo "PARSING GIT BRANCH"
  (git symbolic-ref -q HEAD || git name-rev --name-only --no-undefined --always HEAD) 2> /dev/null
}

prompt() {
    echo -n "%/"
    echo "$(git status)"
}

PS1="$(prompt)"

这是我的setopt输出结果:

interactive
login
monitor
nonomatch
promptsubst
shinstdin
zle

这是纯粹的zsh问题。bash在标题或标记中都没有位置。除非您完全确定您的问题适用于两者(已针对两者测试代码并获得相同结果),否则请勿为其他shell打标签 - 即时引用错误适用于bash,但您的复制器在其他方面不起作用。 - Charles Duffy
顺便提一下 - 使用括号进行分组相当低效。最好使用大括号:{ git symbolic-ref -q HEAD || git name-rev --name-only --no-undefined --always HEAD; } 2>/dev/null - 这样你就不会产生子shell开销了。 - Charles Duffy
1个回答

10

在调用 prompt 前需要延迟,直到提示框显示出来;可以通过使用单引号来实现:

PS1='$(prompt)'

然而,更好的方法是定义一个函数来设置PS1,并将该函数添加到precmd_functions数组中,以便在显示每个提示之前执行它。

prompt () {
    PS1="%/$(git status)"
}

precmd_functions+=(prompt)

你能详细解释一下 ' 和 " 之间的区别吗?拖延调用某个东西具体是什么意思? - George
5
@George,单引号可以抑制shell扩展,因此$()成为存储在PS1中的值的一部分。相比之下,在双引号内,实际存储在PS1中的是立即运行该命令一次后的输出结果。 - Charles Duffy
3
使用单引号时,PS1 被设置为文本字符串 $(prompt),而不是调用 prompt 函数的结果。然而,提示变量是特殊的;当它们被显示时,它们会再次进行一轮评估,因此 $(prompt) 会在每次显示提示时被展开。 - chepner

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