Char
Char

Reputation: 1735

How to change bash prompt color based on exit code of last command?

I want to display a green smile face if the previous exit code is 0 and red smile face if not successful.

Basically I want to do this prompt but with other stuff included.

PS1='\u@\h:\w `if [ $? = 0 ]; then echo \[\e[32m\]:\)\[\e[37m\]; else echo \[\e[31m\]:\(\[\e[37m\]; fi` $ '

I want to abstract the condition logic to a function but when I try to combine these two the escape characters show instead of the colors.

smiley()                                                                       
{
    if [ $? == 0 ]; then
        echo ':)'
    else
        echo ':('
    fi
}
RED="\033[1;5;91m"
GREEN="\033[1;5;92m"
NONE="\033[m"
NORMAL="\[\033[0m\]"
YELLOW="\[\033[1;4;93m\]"
MAGENTA="\[\033[35m\]"
WHITE="\[\033[1;37m\]"
BLINK="\[\033[5m\]"
#INVERT="\[\e[7m\]"
#OFF="\[\033[m\]"

PS1="${YELLOW}\u${MAGENTA}@${YELLOW}\h${NORMAL}:${WHITE}\w $(smiley)\n"

I even tried one line but it didn't work either.

 PS1='\[\033[1;4;93m\]\u\[\033[35m\]@\[\033[1;4;93m\]\h\[\033[0m\]\[\033[1;37m\]    \W if [ $? = 0 ]; then echo \[\e[32m\]:\)\[\e[37m\]; else echo \[\e[31m\]:\(\[\    e[37m\]; fi\n'

If there any way to do this without PROMPT_COMMAND?

Upvotes: 6

Views: 7777

Answers (3)

RJFalconer
RJFalconer

Reputation: 11662

I adapted Michael A's answer for a .bashrc file (in my case, git-for-windows)

git bash rc screenshot

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

For reference the default is:

PS1='\
\[\033]0;$TITLEPREFIX:$PWD\007\]\n\
\[\033[32m\]\u@\h\
\[\033[35m\] $MSYSTEM \
\[\033[33m\]\w\
\[\033[36m\]`__git_ps1`\
\[\033[0m\]\n$'

Upvotes: 0

Michael A.
Michael A.

Reputation: 1209

This works for me:

export PS1="\
\$(if [[ \$? -gt 0 ]]; then printf \"\\[\\033[01;31m\\]\xF0\x9F\x98\xA7\"; else printf \"\\[\\033[01;32m\\]\xF0\x9F\x98\x83\"; fi)\
\[\033[01;30m\]\u\
\[\033[01;33m\]@\
\[\033[01;36m\]\h \
\[\033[01;33m\]\w \
\[\033[01;31m\][\$(__git_ps1 '%s')] \
\[\033[01;35m\]\\$ \
\[\033[00m\]\
"

Upvotes: 2

Scheff's Cat
Scheff's Cat

Reputation: 20141

I assume your quoting is not correct. I fiddled a little bit around with this and finally got it working:

$ bash --version
GNU bash, version 4.4.12(3)-release (i686-pc-cygwin)

$ smiley()
> {
>   if [ "$?" == "0" ]; then
>     echo -e '\e[0;32m:) '
>   else
>     echo -e '\e[0;31m:( '
>   fi
> }

$ PS1="$PS1"'`smiley`'

$ :) rm non-existing
rm: cannot remove 'non-existing': No such file or directory

$ :( echo "Everything fine"
Everything fine

$ :)

I did this on Windows (64 bit) but I guess it should work on Linux (or any other Unix-like) as well.

Notes:

  1. I wrote a function smiley() (a simplified version of your) and checked it by calling it from command line. It worked fine.

  2. I added it to PS1 and it echoed :) in any case. I realized that the bash replacement was already done in assignment of PS1.

  3. Thus, I safed the invocation of smiley by an extra pair of single quotes to defer the invocation until the output of prompt. Now, it works like expected.

  4. Because the questioner required a colored version I made an update. I found the actual solution in this link: SO: How to change the output color of echo in Linux. It's easy to find the necessary terminal escape sequences. The trick is to use echo -e to enable the backslash escaping in echo.

The snapshot below shows how does it look (with colors):

Snapshot of <code>bash</code> with tuned prompt in an <code>xterm</code>

Upvotes: 5

Related Questions