5

On my system, when using a colorized prompt, the last line of the previous command's output gets overwritten if the last character of the output isn't a newline.

Ex: Using the default, non-colored bash prompt, we have:

[myusername@myhostname dirname]$ echo -n foo-bar
foo-bar[myusername@myhostname dirname]$

This is expected.

However, using the following colorized prompt:

PS1='\[\033[1;32m\]\u@\h\[\033[0m\]:\[\033[1;34m\]\w\[\033[0m\]\$ '

we have (shown here without the color):

myusername@myhostname:~/path/to/dirname$ echo -n foo-bar
myusername@myhostname:~/path/to/dirname$ rname$ 

The cursor is now located on the last "r" in the line. Typing some characters at the prompt overwrites the last "rname$". The end result is that if the previous command's output does not end in a newline, I cannot see what it is. This is the most important thing to fix. The way the extra characters appear, but are over writeable, doesn't bother me much, but would also be nice to fix.

I've tried this with other colorized prompts from bash documentation, and some colored prompts from other super user answers regarding colorized prompts, and they all behave the exact same way.

$ bash --version
GNU bash, version 3.1.17(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

Not sure, but I think it's CentOS, don't know what version. Give me a command to check the O.S., and I'll run it.

4
  • 1
    Odd. What operating system and what version of bash? I don't see the described behavior with the given prompt on Mac OS X 10.7.4, using bash 3.2 and bash 4.2. Also, is PROMPT_COMMAND set to anything? I'm afraid I don't have any suggestions, but perhaps someone else can use this information to suggest a solution.
    – chepner
    Jun 22, 2012 at 23:03
  • Can’t reproduce it either – my bash [3.2.48(1)-release (x86_64-apple-darwin11)] on OS X 10.7.4 doesn’t display this behavior in Terminal.app. Considering your color escape codes are correctly bracketed, neither should yours. Try unsetting PROMPT_COMMAND to see if the behavior persists. It would also be helpful if you specified your bash version (run bash -- version) and your OS.
    – kopischke
    Jun 23, 2012 at 15:13
  • Unfamiliar with PROMPT_COMMAND. I've just been setting PS1. unset PROMPT_COMMAND doesn't help. $ echo $PROMPT_COMMAND gives echo -ne "\033_${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}"; echo -ne "\033\\"
    – Eddified
    Jun 30, 2012 at 6:58
  • Note: I edited the original question, added bash version info.
    – Eddified
    Jun 30, 2012 at 7:01

2 Answers 2

5

My preferred solution is simply to have the prompt always begin with a newline. That way I always have a blank line between the last command output (except in this case, of course), which feels more natural to me. And the worst case is that instead of overwriting text like you are seeing, I don't get the blank line in between. Unless you try it out for a while and simply can't stand the blank line, I highly recommend it.

PS1='\n\[\033[1;32m\]\u@\h\[\033[0m\]:\[\033[1;34m\]\w\[\033[0m\]\$ '

An additional suggestion, if you're up for it: I also use a multi-line prompt to make my command line as long as possible before wrapping (or scrolling if your terminal or shell is configured for that). I also like to know the history line number. Those two together:

PS1='\n\[\033[1;32m\]\u@\h\[\033[0m\]:\[\033[1;34m\]\w\[\033[0m \!\]\n\$ '

Finally, I also like to get timestamps printed before and after running commands. A simplified version of what I use for that is:

export PROMPT_COMMAND="date +\"%Y-%m-%d %H:%M:%S (%s)\"; trap 'date +\"%Y-%m-%d %H:%M:%S (%s)\"; trap DEBUG' DEBUG"

Head spinning yet? :)

1
  • 3
    This neatly sidesteps OP’s issue, but it doesn’t address OP’s problem – which would be worth investigating considering the issue is not reproducible on OS X systems (1, 2), for instance (is it on yours?).
    – kopischke
    Jun 23, 2012 at 15:16
0

A simple & elegant solution is to check if the cursor is in 1st column and issue a newline if that's not the case. I have already written this answer for another question, you can take a look: https://serverfault.com/a/1131155/539096

Here is a brief of that answer:

You can detect the cursor position using this command: IFS=';' read -sdR -p $'\E[6n' ROW COL.
The COL variable holds the current column where the cursor is. If $COL is not equal to 1, add a newline before setting the PS1 variable.

Here is my implementation:

_set_prompt() {
    IFS=';' read -sdR -p $'\E[6n' ROW COL # Get cursor position
    [ $COL -ne 1 ] && echo '' # Add newline if cursor is not at 1st column
    PS1="........." # Your PS1 variable
}

PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'_set_prompt'

Most readymade prompts allow customization, so you can easily add this check.

You must log in to answer this question.

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