【问题标题】:Include non-0 exit codes in the subsequent bash prompt在随后的 bash 提示符中包含非 0 退出代码
【发布时间】:2011-08-22 06:11:00
【问题描述】:

有时,我会运行一个输出很多的命令。有时,该输出的最后 30-40 行(也就是我真正看到的输出的唯一部分)很好,但更进一步,出现了错误。我想让更容易注意到命令失败。为此,我希望返回码成为我的提示的一部分。所以我拿走了我的 $PS1:

[\D{%Y-%m-%d} \t] \[\e]0;\u@\h: \w\a\]\$

...并将其扩展为:

[\D{%Y-%m-%d} \t] ${?/^0$/} \[\e]0;\u@\h: \w\a\]\$

这会导致如下提示:

[2011-05-10 09:38:07] 0 soren@lenny:~$ 

但是,我想找到一种方法,让它只包含非 0 的退出代码。我怎样才能做到这一点?当然,我可以使用

$(echo \$? | sed -e blah)

尽管 sed 很轻量级,但它仍然比 bash 的内置内容重很多。

【问题讨论】:

标签: bash command-prompt


【解决方案1】:

一点点printf滥用:

printf '%.*s' $? $?

【讨论】:

  • 这既有效又让我发笑。我喜欢。我将它稍微扩展为:printf '%.*s%.*s' $? $? $? ' ' 这使它只有在非零时才添加一个空格。
  • 为了完整起见:在 primpt 中使用 $(foo) 只会评估 foo 一次(而不是在每个命令中)。请参阅 stackoverflow.com/questions/16715103/… 了解如何解决此问题。
【解决方案2】:

以下对我有用:

PS1="[\D{%Y-%m-%d} \t] \u@\h:\w\a \${?##0} \$ "

示例当 $?为 0:

[2011-07-25 11:56:57] plars@plars-t500:~  $<br>
there is an extra space there ---------^^ not sure if that's a problem for you

示例当 $?是 130:

[2011-07-25 11:57:39] plars@plars-t500:~ 130 $

【讨论】:

    【解决方案3】:

    您可以使用 bash 的内置模式匹配:

    $ rc=0
    $ echo ${rc##0}
    
    $ rc=123
    $ echo ${rc##0}
    123
    

    【讨论】:

    • 这也是我的第一个想法,但我拒绝了它,认为它只会去掉任何 0,但当然不是这样。这似乎可以解决问题。唯一的缺点是退出代码为 0 时会出现多余的空间。
    • 如果您想了解更多信息,请查看tldp.org/LDP/abs/html/string-manipulation.html的“子字符串删除”部分
    【解决方案4】:

    这是我在.bashrc 中使用的,用于获取带有退出代码的红色数字。冗长,但它可以完成工作并且应该是可移植的。

    highlight()
    {
        if [ -x /usr/bin/tput ]
        then
            tput bold
            tput setaf $1
        fi
        shift
        printf -- "$@"
        if [ -x /usr/bin/tput ]
        then
            tput sgr0
        fi
    }
    
    highlight_error()
    {
        highlight 1 "$@"
    }
    
    highlight_exit_code()
    {
        exit_code=$?
        if [ $exit_code -ne 0 ]
        then
            highlight_error "$exit_code "
        fi
    }
    
    PS1='$(highlight_exit_code)...'
    

    【讨论】:

      【解决方案5】:

      您可以在 PS1 中放置一个 if 语句,它仅在退出状态为非零时才回显退出状态:

      PS1='[\D{%Y-%m-%d} \t] $(es=$?; if [ $es -ne 0 ]; then echo $es; fi) \[\e]0;\u@\h: \w\a\]\$'
      

      【讨论】:

      • 这是我使用的方法,因为它允许使用else 子句。请注意将$? 复制到局部变量的重要性,因为[ 将在到达echo 之前覆盖它。
      【解决方案6】:

      执行此操作的常用方法是在命令失败时使用trap ... ERR 执行任意代码:

       $ trap 'echo $?' ERR
       $ true
       $ false
      1
       $
      

      一个经典的 UNIX 恶作剧是trap 'echo You have new mail.' ERR

      【讨论】:

        【解决方案7】:

        对于 zsh 用户:将其插入到您的提示中:%(?,, -%?-)

        【讨论】:

          【解决方案8】:

          这是我使用的提示,插入 .bashrc 并获取它以使用它。如您所见,仅在值不为 0 的情况下才将 PREV_RET_VAL 附加到 PS1。

          COLOR_RED_BOLD="\[\e[31;1m\]"
          COLOR_GREEN_BOLD="\[\e[32;1m\]"
          COLOR_NONE="\[\e[0m\]"
          
          # prompt function
          promptFunc()
          {
          PREV_RET_VAL=$?;
          
          PS1=""
          
          PS1="${PS1}\e[1;30m[\e[1;34m\u@\H\e[1;30m:\e[0;37m \e[0;32m\d \T\e[1;30m]\e[1;37m \w\e[0;37m\[\033]0; \w - \u@\H \007\]\n\[\] "
          
          if test $PREV_RET_VAL -eq 0
          then
              PS1="${PS1}${COLOR_GREEN_BOLD}\\$ ${COLOR_NONE}"
          else
              PS1="${PS1}${COLOR_RED_BOLD}\\$ [${PREV_RET_VAL}] ${COLOR_NONE}"
          fi
          }
          
          PROMPT_COMMAND=promptFunc
          

          【讨论】:

            【解决方案9】:

            单引号示例:

            PS1='${?#0}&gt; '

            双引号示例(注意额外的反斜杠以转义 $

            PS1="\${?#0}&gt; "

            样本输出:

            > echo 'ok'
            ok
            > bogus
            bogus: command not found
            127> 
            

            解释:${var#pattern} 是一个 bash 参数扩展,意思是从 $var 前面删除最短匹配模式。所以在这种情况下,我们从$? 的前面删除0,这将有效地截断0 的退出代码。

            如果使用双引号,$? 将在设置 PS1 时被替换,而不是每次都被评估。执行echo $PS1 以确认您在PS1 中没有硬编码值。

            【讨论】:

              猜你喜欢
              • 2013-05-18
              • 1970-01-01
              • 2010-09-21
              • 2013-04-27
              • 2018-05-09
              • 2014-01-05
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多