I'm trying to set up a bash prompt for - hostname(screen#):directory$ which is coloured green if the last command completed successfully, red if not. This is what I have so far, which actually does the job but seems to cause display problems if the command wraps a line:

 PS1="\[\`if [[ \$? = "0" ]]; then echo '\e[32m'; else echo '\e[31m' ; fi\` - \h(${WINDOW}):\W$\e[00m "

Googling the issue I found this helpful SO post with a comment that mentions wrapping nonprinting characters in \\[ and \\] to avoid this issue. Therefore I tried the following, but it did not solve the issue, and furthermore breaks the colour change:

PS1="\[\`if [[ \$? = "0" ]]; then echo '\e[32m'; else echo '\e[31m' ; fi\`\] - \h(${WINDOW}):\W$\[\e[00m\] "

How can I keep the structure of this prompt, with colours, but fix it so that long commands are displayed properly?

4 Answers 4


I have a fancy prompt with colors, and now bash doesn't seem to know how wide my terminal is. Lines wrap around incorrectly.

I have another proper way to do this, put this code in your ~/.bashrc or create a new file and source file :



    RED=$(tput setaf 1)
    GREEN=$(tput setaf 2)
    STOP=$(tput sgr0)

    # arithmetic using bash parameter expansion on a array
    if (($retval + ${PIPESTATUS[@]/%/+} + 0)); then
        PS1="\[$RED\]\u@\h:\w$ \[$STOP\]"
        PS1="\[$GREEN\]\u@\h:\w$ \[$STOP\]"

That will do the trick =)

Bash will run the code inside PROMPT_COMMAND for each commands.

If you have copy/paste problem, you can download the script



  • (( )) is arithmetic in bash, see http://wiki.bash-hackers.org/syntax/arith_expr
  • PROMPT_COMMAND : if set, the value is executed as a command prior to issuing each primary prompt. See man bash | less +/PROMPT_COMMAND
  • tput is better than hard coding ANSI escape codes. See http://wiki.bash-hackers.org/scripting/terminalcodes
  • PIPESTATUS : An array variable containing a list of exit status values from the processes in the most-recently-executed foreground pipeline (which may contain only a single command). See man bash | less +/PIPESTATUS
  • cat<<-'EOF' is a special here doc : the - character means I can indent code, and the single quotes on 'EOF' means to not interpolate variables
  • Added doc link about your problem Nov 20, 2012 at 21:15
  • Thanks. I am getting an unexpected EOF while looking for matching `)' on the line that defines the function. Near as I can tell it seems that bash thinks that there is an unclosed ( in the do line, but I really don't see how that could be.
    – dotancohen
    Nov 20, 2012 at 22:07
  • This is a copy & paste problem, this will disappear if you reindent. Nov 20, 2012 at 22:16
  • Actually, I did reindent, with tabs. Everything inside the function got one tab save for the lines that begin PS1, which got two tabs.
    – dotancohen
    Nov 20, 2012 at 22:26
  • 1
    Thank you Sputnik! I learned a lot from this post, not only about the prompt but about other aspects as well. You were very helpful and I've found some goodies in you back posts as well that I'm going through to learn from. Thanks!
    – dotancohen
    Nov 20, 2012 at 22:46

I have a 2-line prompt, so the potentially long stuff won't affect the command line:

glennj@homebase ~/tmp
2219 $ set | grep PS1=
PS1='\n\u@\h \w\n\! \$ '
  • So useful! I have had this in a custom prompt for grass.osgeo.org and now trying in the regular bash prompt too. It does away the non-clobbering problem. Nov 22, 2015 at 7:10

Not \\[, just \[. You also have an extra \[ at the start.

  • Thanks, I updated the question. In fact, I had already taken care of the `\\` issue before I posted.
    – dotancohen
    Nov 20, 2012 at 19:12

This is not a direct answer to the original question, it is just a usage example.

Based and thanks to @stArdustͲ's answer, I found a proper solution for a custom command prompt to show up the battery's status*, on the top right corner of the terminal. The colors are defined in an independent file which is sourced from inside .bashrc.

    function battery_percentage {
        PERCENTAGE=$(upower -i $(echo $(upower -e |grep 'battery')) |grep 'percentage' |sed -e 's/^[ \t]*//;s/[[:space:]]\+/ /g;s/[ \t]*$//' |cut -d' ' -f2 |cut -d"%" -f1)
        if [ "${PERCENTAGE}" -lt 15 ]
            then PColor='BlinkIRed'
            else PColor='Gray'
        echo "\001${!BColor}\002Battery\001${!PColor}\002 ${PERCENTAGE}% \001${Reset}\002"

    function battery_time {
        TIME=$(upower -i $(echo $(upower -e |grep 'battery')) |grep 'time' |sed -e 's/^[ \t]*//;s/[[:space:]]\+/ /g;s/[ \t]*$//' |cut -d' ' -f4,5)
        echo "\001${IGray}\002${TIME}\001${Reset}\002"

    export PS1="\[\e[s\]\[\e[1;\$((COLUMNS-26))f\]$(battery_percentage) $(battery_time)\[\e[u\]${PS1}"

Finally, the PS1 looks like:

\[\e[s\]\[\e[1;$((COLUMNS-26))f\]\001\e[0;38;5;8m\002Battery\001\e[0;38;5;7m\002 82% \001\e[0m\002 \001\e[0;38;5;8m\0023.6 hours\001\e[0m\002\[\e[u\]\[\e[0;38;5;232m\]\[\e[48;5;5m\] \u \[\e[0;38;5;5m\]\[\e[48;5;11m\] \[\e[0;38;5;232m\]\[\e[48;5;11m\]@\H \[\e[0;38;5;11m\]\[\e[48;5;0m\]\[\e[0m\] \[\e[0;38;5;6m\]\w\a \[\e[1;38;5;5m\]→\e[0m

Note, I do have some cursor positioning problems, though, when I scroll up and down through the command history.

* of a ThinkPad laptop

  • 1
    Though it doesn't answer the question, this answer does give some nice usage examples. Thanks.
    – dotancohen
    Apr 6, 2015 at 11:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .