Search code examples
bashps1

How to empty the value of $? variable in .bashrc?


I've been trying to customize my bash prompt so that it'll look like

┌─[error_code_if_not_zero]─[time_short]─[username]─[current_folder]─[git_branch]
└─▪ 

And here is my .bashrc:

# command completion
source /home/falcon/.bin/git-prompt.sh

GIT_PS1_SHOWDIRTYSTATE=1
GIT_PS1_SHOWSTASHSTATE=1
GIT_PS1_SHOWUNTRACKEDFILES=1
GIT_PS1_SHOWUPSTREAM="auto"

# function to generate the prompt
function __prompt_command() {
    __exit_code="$?"
    __error_int="";
    if [ $__exit_code -ne 0 ]; then
        __error_int="[\[\e[0;31m\]$__exit_code\[\e[0;37m\]]─"
    fi

    PS1="\[\e[0;37m\]┌─$__error_int[\A]─[\[\e[0;35m\]\u\[\e[0;37m\]]─[\[\e[0;33m\]\w\[\e[0;37m\]]\$(__git_ps1 '─[\[\e[0;31m\]%s\[\e[0;37m\]]')\n\[\e[0;37m\]└─▪ \[\e[0;m\]"
}

export PROMPT_COMMAND=__prompt_command

This configuration works fine, it is showing the error code when it's non-zero. But the trouble comes whem i'm just pressing enter in terminal (calling empty commands) - the returning value remains the same as the returning value of the last non-empty command. For example, this happened when i'm just pressing enter in terminal:

┌─[127]─[02:51]─[falcon]─[~]
└─▪ 
┌─[127]─[02:51]─[falcon]─[~]
└─▪ 
┌─[127]─[02:51]─[falcon]─[~]
└─▪ 
┌─[127]─[02:51]─[falcon]─[~]
└─▪ 

As you can see, the error code 127 remains even after an empty command. But i'm expecting something like this:

┌─[127]─[02:51]─[falcon]─[~]
└─▪ 
┌─[02:51]─[falcon]─[~]
└─▪ 
┌─[02:51]─[falcon]─[~]
└─▪ 
┌─[02:51]─[falcon]─[~]
└─▪ 

So, my question is, how to empty the value of $? inside the function __prompt_command?


Solution

  • Got it. First, credit where it's due--anubhava in the mentioned "Detect Empty Command" question is the author of much of this code.

    Still, it works the way you want (as far as I can tell).

    # command completion
    source /home/falcon/.bin/git-prompt.sh
    
    GIT_PS1_SHOWDIRTYSTATE=1
    GIT_PS1_SHOWSTASHSTATE=1
    GIT_PS1_SHOWUNTRACKEDFILES=1
    GIT_PS1_SHOWUPSTREAM="auto"
    
    # function to generate the prompt
    PS1="\[\e[0;37m\]┌─\$([[ -n \$_ret ]] && echo \"[\[\e[0;31m\]\$_ret\[\e[0;37m\]]-\")[\A]─[\[\e[0;32m\]\u\[\e[0;37m\]]─[\[\e[0;33m\]\w\[\e[0;37m\]]\$(__git_ps1 '─[\[\e[0;31m\]%s\[\e[0;37m\]]')\n\[\e[0;37m\]└─▪ \[\e[0;m\]"
    trapDbg() {
       local c="$BASH_COMMAND"
       [[ "$c" != "pc" ]] && export _cmd="$c"
    }
    
    pc() {
       local r=$?
       if [[ $r == 0 ]]; then
          r=''
       fi
       trap "" DEBUG
       [[ -n "$_cmd" ]] && _ret="$r" || _ret=""
       export _ret
       export _cmd=
       trap 'trapDbg' DEBUG
    }
    
    export PROMPT_COMMAND=pc
    trap 'trapDbg' DEBUG
    

    I combined your code and his, and modified the PS1. It now includes logic to only display the square brackets when $_ret is set. Also, anubhava's code always displayed a return code, including 0. I added the conditional bit to unset when return code was 0.

    Anyhow, there you have it.

    Note: I don't have whatever git-prompt.sh contains, so I tested without that bit. Hopefully that doesn't drastically change anything.