Bash 和zsh 提示响铃并显示上一条命令的错误代码

Bash and Zsh prompt that ring a bell and do display error code of last command

我想在 Bash 和 Zsh 中都有相同的提示。我希望它:

在Bash中,我有:

BLK="\[$(tput setaf 0; tput bold)\]"
RED="\[$(tput setaf 1; tput bold)\]"
grn="\[$(tput setaf 2)\]"
GRN="\[$(tput setaf 2; tput bold)\]"
yel="\[$(tput setaf 3)\]"
reset_color="\[$(tput sgr0)\]"

PS1='\n\
`if [[ $? -gt 0 ]]; then printf "\[3[01;31m\]$?"; tput bel; else printf "\[3[01;32m\]0"; fi`\
\[3]0;$PWD[=11=]7\] \
\[3[0;32m\]\u@\h\
\[3[01;30m\]:\
\[3[;;33m\]\w\
\[3[36m\]`__git_ps1`\
\[3[0m\]\n$ '

在 Zsh 中,这是我的配置:

BLK=$(tput setaf 0; tput bold)
RED=$(tput setaf 1; tput bold)
grn=$(tput setaf 2)
GRN=$(tput setaf 2; tput bold)
yel=$(tput setaf 3)
reset_color=$(tput sgr0)

PROMPT="
%(?.$GRN.$RED)%?$reset_color $grn%n@%m$BLK:$reset_color$yel%~ $reset_color
%(!.#.$) "

这是它在终端中的样子:

当最后一个命令出错时,两个提示都会响铃。 但是,in Bash,它打印 0 而不是命令的正确 return 代码 失败。

如何解决?

PS-欢迎任何改进上述代码的更好方法!

任何外部命令(例如printftput)都会重置$?的值。您需要在此之前将其捕获到变量中。

rc=$?
if [ $rc -gt 0 ]; then
  printf "\[3[01;31m\]$rc"
  tput bel
else
  printf "\[3[01;32m\]0"
fi

(为便于阅读而展开;这将替换反引号内的代码。)

注意,这仍然会覆盖 $? 的值;也许在末尾添加 exit $? 以正确保留值。

测试 $? 本身的命令 $? 重置为测试结果。您需要先保存要显示的值。

PS1='\n\
$(st=$?; if [[ $st -gt 0 ]]; then printf "\[3[01;31m\]$st"; tput bel; else printf "\[3[01;32m\]0"; fi)\
\[3]0;$PWD[=10=]7\] \
\[3[0;32m\]\u@\h\
\[3[01;30m\]:\
\[3[;;33m\]\w\
\[3[36m\]`__git_ps1`\
\[3[0m\]\n$ '

我建议使用 PROMPT_COMMAND 来构建 PS1 的值,而不是嵌入可执行代码。这给了你更大的灵活性 用于评论并将您需要的任何计算与实际计算分开 格式化。 make_prompt不需要相当那么多行,但它是 只是一个演示。

set_title () {
    printf '3]0;%s%s' "" "$(tput bel)"
}

make_prompt () {
  local st=$?
  local c bell
  bell=$(tput bel)

  # Green for success, red and a bell for failure
  if [[ $st -gt 0 ]]; then
    c=31
  else
    c=32 bell=
  fi
 
  win_title=$(set_title "$PWD")
  git_status=$(__git_ps1)

  PS1="\n"
  PS1+="\[\e[01;${c}m$bell\]"  # exit status color and bell
  PS1+=$st
  PS1+="\[$win_title\]"  # Set the title of the window
  PS1+="\[\e[0;32m\]"    # Color for user and host
  PS1+="\u@\h"
  PS1+="\[\e[01;30m\]"   # Color for : separator
  PS1+=":"
  PS1+="\[\e[;;33m\]"    # Color for directory
  PS1+="\w"
  PS1+="\[\e[36m\]"      # Color for git branch
  PS1+=$git_status
  PS1+="\[\e[0m\]"       # Reset to terminal defaults
  PS1+="\n$ "
}

PROMPT_COMMAND=make_prompt

zsh 已经有用于添加颜色的与终端无关的转义序列。

PROMPT="%B%(?.%F{green}.%F{red}$(tput bel))%?%f%b %F{green}%n@%m%F{black}%B:%b%F{yellow}%~ %f%(!.#.$) "