问题
I\'m using custom bash prompt to show git branch.
Everything is in /etc/bash/bashrc
:
function formattedGitBranch {
_branch=\"$(git branch 2>/dev/null | sed -e \"/^\\s/d\" -e \"s/^\\*\\s//\")\"
# tried these:
echo -e \"\\e[0;91m ($_branch)\"
echo -e \"\\e[0;91m ($_branch) \\e[m\"
echo -e $\'\\e[0;91m\'\"($_branch)\"
echo \"($_branch)\"
echo \"$(tput setaf 2) ($_branch) $(tput setaf 9)\"
printf \"\\e[0;91m ($_branch)\"
}
# color is set before function call
PS1=\'\\[\\033[01;34m\\] \\[\\033[0;91m\\]$(formattedGitBranch) \\$\\[\\033[00m\\] \'
# color is set inside function
PS1=\'\\[\\033[01;34m\\] $(formattedGitBranch) \\$\\[\\033[00m\\] \'
Problem is that when I set color for $_branch
in the function, my prompt will be overwritten when EOL is reached:
Tried all possible variants tput
, printf
, $\'\'
notation.
I solved the problem by setting the colour only in PS1
:
But..
- I would like to know why it is overwriting my prompt
- How to fix this issue when function is used
I\'m using Gentoo Linux. GNU bash, verze 4.2.37(1)-release (i686-pc-linux-gnu)
回答1:
1) I would like to know why it is overwriting my prompt
Because every non-printable characters have to be escaped by \[
and \]
otherwise readline cannot keep track of the cursor position correctly.
You must put
\[
and\]
around any non-printing escape sequences in your prompt.
Without the\[ \]
bash will think the bytes which constitute the escape sequences for the color codes will actually take up space on the screen, so bash won't be able to know where the cursor actually is.
\[
Begin a sequence of non-printing characters. (like color escape sequences). This allows bash to calculate word wrapping correctly.
\]
End a sequence of non-printing characters. -- BashFAQ...note the escapes for the non printing characters, these ensure that readline can keep track of the cursor position correctly. -- ss64.com
2) How to fix this issue when function
is used
If you want to set colours inside a function
whose output is used in PS
you have two options.
Either escape the whole function call:
PS1='\[ $(formattedGitBranch) \] '
Or replace the non-printing Escape sequences inside
echo
. That is, replace:\[
and\]
with\001
\002
(thanks to user grawity!)
echo -e
is not aware of bash's\[
\]
so you have to substitute these with\001
&\002
ASCII control codes to delimit non-printable chars from printable:function formattedGitBranch { echo -e "\001\e[0;91m\002 ($_branch)"; }
PS1='$(formattedGitBranch) '
回答2:
Strings like \e[0;91m
needs additional quoting, to prevent bash from calculating its length.
Enclose these strings from formattedGitBranch
in \[
& \]
as, \[\e[0;91m\]
You have done it correctly in other places. Just missed it in formattedGitBranch.
回答3:
You have to take care of non printable character inside [\ and /] otherwise you might be getting cursor right on top of command prompt as shared in question itself , so I found something and just sharing it :-
For getting cursor after PS1 output on the same line :
few examples :
PS1='[\u@\h:\w]\$
PS1='[\[\033[0;32m\]\u@\h:\[\033[36m\]\W\[\033[0m\]]\$ '
Refer Link : syntax for bash PS1
来源:https://stackoverflow.com/questions/19092488/custom-bash-prompt-is-overwriting-itself