【问题标题】:Bash and Zsh prompt that ring a bell and do display error code of last commandBash 和 Zsh 提示响铃并显示最后一个命令的错误代码
【发布时间】:2020-02-20 15:48:01
【问题描述】:

我希望在 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 "\[\033[01;31m\]$?"; tput bel; else printf "\[\033[01;32m\]0"; fi`\
\[\033]0;$PWD\007\] \
\[\033[0;32m\]\u@\h\
\[\033[01;30m\]:\
\[\033[;;33m\]\w\
\[\033[36m\]`__git_ps1`\
\[\033[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
%(!.#.$) "

这就是它在终端中的样子:

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

如何解决?

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

【问题讨论】:

    标签: bash return-value command-prompt zsh prompt


    【解决方案1】:

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

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

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

    set_title () {
        printf '\033]0;%s%s' "$1" "$(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%(!.#.$) "
    

    【讨论】:

    • 完成。工作完美。只需复制/粘贴……一个梦想!
    • 我假设退出状态是提示符上最后执行的命令..它“不”为我工作..
    • 应该是,但是make_prompt有错误。我设置st=$? 的原因是在我开始使用函数中的其他命令踩踏它之前保留最后一个命令的退出状态......然后我去运行tput(和local,就此而言) 在它之前。我会解决的。
    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      • 2023-03-08
      • 2013-05-18
      • 1970-01-01
      • 2012-02-14
      • 1970-01-01
      相关资源
      最近更新 更多