Search code examples
bashpromptps1

Correct return value in BASH prompt


This is part of a .bashrc file that sets a prompt, on a Ubuntu 19.10 machine:

# Terminal tab name in gnome-terminal or Guake
PROMPT_COMMAND='echo -ne "\033]0;$(basename ${PWD})\007"'

GIT_PS1_SHOWCOLORHINTS=yes
RET=\$?
source /usr/lib/git-core/git-sh-prompt

if [ "$color_prompt" = yes ]; then
    color_reset=$(tput sgr0)
    color_bold=$(tput bold)
    color_white=$(tput setaf 7)
    color_jobs=$(tput setaf 7)
    color_user=$(tput setaf 3)
    color_dir=$(tput setaf 4)
    color_load=$(tput setaf 5)
    color_succeed=$(tput setaf 2)
    color_fail=$(tput setaf 1)
    sep=$(tput setaf 7)\)
    PS1="${color_user}\u${sep}\[\D{%T}\]${sep}${color_reset}\$(__git_ps1)${color_dir}\W${color_reset}${sep}\`if [[ ${RET} == 0 ]]; then echo \"${color_succeed}0\"; else echo \"${color_fail}${RET}\"; fi\`${color_white}${sep}${color_reset}\$ "
else
    PS1="\u${sep}\[\D{%T}\]${sep}\$(__git_ps1)\W${sep}\`if [[ ${RET} == 0 ]]; then echo \"0\"; else echo \"${RET}\"; fi\`${sep}\$ "
fi

and this is an example of the command line in use:

snim2)10:39:53)dirname)0)$ cd scratch
snim2)10:39:54)scratch)0)$ git init
Initialised empty Git repository in .../scratch/.git/
snim2)10:39:56) (master)scratch)0)$ asdasda
asdasda: command not found
snim2)10:40:05) (master)scratch)1)$ $?
127: command not found
snim2)10:40:10) (master)scratch)1)$ 

As you can see, when the return code of a command is non-zero, it appears as 1) in the prompt, rather than showing the correct return code -- in this case 127). How can this be fixed?


Solution

  • You do:

    ..$(__git_ps1)...\`if [[ $? == 0 ]];
    

    The $? is going to be return status of __git_ps1 not the last executed command on command line.

    Try saving the exit return value in the first command substitution block right away:

    if [ "$color_prompt" = yes ]; then
        color_reset=$(tput sgr0)
        color_bold=$(tput bold)
        color_white=$(tput setaf 7)
        color_jobs=$(tput setaf 7)
        color_user=$(tput setaf 3)
        color_dir=$(tput setaf 4)
        color_load=$(tput setaf 5)
        color_succeed=$(tput setaf 2)
        color_fail=$(tput setaf 1)
        sep=$(tput setaf 7)\)
    else
        color_reset=
        color_bold=
        color_white=
        color_jobs=
        color_user=
        color_dir=
        color_load=
        color_succeed=
        color_fail=
        sep=\)  # remove the braces...
    fi
    
    # note the quotes - "" expand at setting time, '' expand at runtime
    PS1=
    PS1+="${color_user}\u${sep}\[\D{%T}\]${sep}${color_reset}"
    PS1+='$('
       PS1+='ret=$?; '  # first thing we do - save the exit return value
       PS1+='__git_ps1; '
       PS1+='printf "%s" "'
          PS1+="${color_dir}\W${color_reset}${sep}"
          PS1+='"; '
       PS1+='if ((ret == 0)); then '
           PS1+='printf "%s" "'
              PS1+="${color_succeed}"  # expand variable on assignment side
              PS1+='0"; '  # this looks strange. Just print first the color, then $ret...
       PS1+='else '
          PS1+='printf "%s" "'
               PS1+="$color_fail"
               PS1+='$ret"; '
       PS1+='fi '
    PS1+=')'
    PS1+="${color_white}${sep}${color_reset}"
    PS1+='\$ '  # note - this is *not* "\$ "