4

I want to have really complex prompt. It should contains login, computer name, date, time, working directory, result of last command and new line symbol. I want to color each item as well. So I inserted into my .bashrc some kind of monster like this one:

# login and computer name
PS1='[\e[1;37m\]\u\e[m\]@\e[1;32m\]\h\e[m\]] '
# date, time and working directory
PS1=$PS1'[\e[1;34m\]\D{%Y-%m-%d} \e[1;35m\]\t\e[m\]] \e[1;33m\]\w\e[m\] '
# result of last command and command prompt in new line
PS1=$PS1'\e[1;31m\]${?#0}\e[m\]\n \e[1;36m\]\$\e[m\] '

I do know it is terrible solution, but I have too little experience with bash to improve this. But this is not the only one problem.

 $ aaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bash: bbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: command not found...

After the last a I pressed Home key, but visual caret didn't go to the beginning of the command. As you can see, actual caret went to the beginning. Why this occurred? How can I improve my command prompt in my .bashrc?


Update:

After using @Groxxda advice, I've got one another problem. My .bashrc PS1 definition looks like this one. Described issue doesn't occur now. But if in my command history I have ls and before this I have cat script.sh, and if I push arrow up twice, I have got command like cat scls and buffer has only two signs (only ls). Why this occurs? How can I manage this?

  • 2
    Check your \[ \] escapes. This tells bash that the content between does not print visible characters. You should put them around the color codes. – groxxda Aug 3 '14 at 11:54
  • works great! why didn't you answered but only commented? – pt12lol Aug 3 '14 at 12:04
  • @Groxxda yes, this is the answer - so make it a full answer – Volker Siegel Aug 3 '14 at 12:45
  • I've got one another problem. After upgrade by @Groxxda, my .bashrc PS1 definition looks like this one: pastebin.com/EZDn6VkP. Described issue doesn't occurs now. But if in my command history I have ls and before this I have cat script.sh, and if I push arrow twice, I have got command like cat scls and buffer has only two signs (only ls). Why this occurs? How can I manage this? – pt12lol Aug 3 '14 at 16:19
  • The original question is a duplicate of unix.stackexchange.com/questions/28827/…. I'm not sure I understand the duplicate, but it looks like it's still the same issue: you need to wrap all zero-width parts of the prompt in \[…\]. – Gilles Aug 3 '14 at 20:45
3

You need to enclose invisible parts of the prompt text in \[ and \].
That is used by bash to calculate the length of the complete prompt, so it can determine where the cursor will be after printing it.
For example, ANSI color escape codes are invisible - they change the color for text that will be output later. They need to be enclosed like this:

\e[1;35m becomes \[\e[1;35m\]

In your update, you write that this helped, but that there is another problem:
the screen does not get cleared at the right locations if you use the history with Up/Down.

This is just another aspect of the first problem: The calculation of the prompt text length is wrong.

Let's take a look at the corrected prompt text from your link:

# login and computer name                                                      
PS1='[\e[\[1;37m\]\]\u\e[\[m\]\]@\e[\[1;32m\]\]\h\e[\[m\]\]] '                  
# date, time                                                                    
PS1=$PS1'[\e[\[1;34m\]\]\D{%Y-%m-%d} \e[\[1;35m\]\]\t\e[\[m\]\]] '              
# working directory and result of last command                                  
PS1=$PS1'\e[\[1;33m\]\]\w\e[\[m\]\] \e[\[1;31m\]\]${?#0}\e[\[m\]\]\n '          
# command prompt                                                                
PS1=$PS1'\e[\[1;36m\]\]\$\e[\[m\]\] '

The problem is that the \[ and \] are not enclosing the whole color escape sequences:
The prompt starts with

[\e[\[1;37m\]\]... 

The color escape sequence in this is \e[1;37m. So the escape character \e, and the [ are outside. At least the [ will be counted as visible. Also, there are two closing \] - it may not cause a problem, but is at least confusing - they can not be nested.
The correct way to write it is:

[\[\e[1;37m\]... 

The other color escape sequences have the same problem.

  • I moved my .bashrc file to Ubuntu and some strange problem appeared again. postimg.org/image/7auk9ziex - here is a screenshot and problematic sign is that one yellow in the end of the first line. If you pay attention, there are two signs in one slot - that some strange one and '~'. What is the problem? How can I help? .bashrc is still in my repo in github - github.com/pt12lol/dotfiles/blob/master/.bashrc. – pt12lol Feb 15 '15 at 11:30
2

You should modularize this some - it would make it much easier to track:

CS='\[\033[1;3' CE='m\]'
WT=${CS}7${CE} LB=${CS}6${CE} PR=${CS}5${CE} \
DB=${CS}4${CE} YL=${CS}3${CE} GN=${CS}2${CE} RD=${CS}1${CE} 
CE='\[\033[m\]' CS=

Now you do your things:

# login and computer name                                                      
PS1="[${WT}\u${CE}@${GN}\h${CE}] "

...

And so on.. You see? It's a little easier to tell what's going on that way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.