自定义Bash提示会覆盖自己

A.D*_*.D. 32 bash gentoo command-prompt

我正在使用自定义bash提示来显示git分支.

一切都在/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\] '
Run Code Online (Sandbox Code Playgroud)

问题是,当我$_branch在函数中设置颜色时,到达EOL时我的提示将被覆盖:

mmmmmmmmmmmmp/rainyday.js(主)$ mmmmmmmm

尝试了所有可能的变体tput,printf,$''符号.

我通过以下方式设置颜色来解决问题PS1:

ad @ gentoo /tmp/rainyday.js(master)$ mmmmmmm

但..

  1. 我想知道为什么它会覆盖我的提示
  2. 如何在使用函数时解决此问题

我正在使用Gentoo Linux. GNU bash, verze 4.2.37(1)-release (i686-pc-linux-gnu)

A.D*_*.D. 48

1)我想知道为什么它会覆盖我的提示

因为每个不可打印的字符都必须被转义\[,\]否则readline无法正确跟踪光标位置.

您必须在提示符中放置\[\]打开任何非打印转义序列.
没有\[ \]bash会认为构成颜色代码转义序列的字节实际上占用了屏幕上的空间,因此bash将无法知道光标实际位于何处.

\[ 开始一系列非打印字符.(如颜色转义序列).这允许bash正确计算自动换行.

\] 结束一系列非打印字符.- BashFAQ

...注意非打印字符的转义,这些确保读取线可以正确跟踪光标位置.- ss64.com

2)如何解决这一问题,当function使用

如果要在使用function其输出的内部设置颜色,则PS有两个选项.

  • 要么逃避整个函数调用:

    PS1='\[ $(formattedGitBranch) \] '

  • 或者替换里面的非打印转义序列echo.也就是说,替换:

    \[\]\001 \002

    (感谢用户的重视!)

  • echo -e 我不知道 bash的,\[ \]所以你必须用\001&\002ASCII控制代码替换这些代码来从printtable中划分不可打印的字符:

    function formattedGitBranch { echo -e "\001\e[0;91m\002 ($_branch)"; } PS1='$(formattedGitBranch) '

  • 如果还不是很明显:除了确保所有不可打印的字符都包含在`\ [``\]中之外,还必须确保所有*printable*字符*都不被*包装.错误地包装可打印字符会导致相同类型的问题,如无法包装不可打印的字符. (3认同)
  • [链接](https://superuser.com/a/301355/140711) 还建议 **使用十六进制版本** `\x01` 和 `\x02` 以避免“bash bug,导致它在处理八进制转义符时吃掉了太多的一位数字”。 (2认同)

ani*_*ane 11

字符串\e[0;91m需要额外的引用,以防止bash计算其长度.

将这些字符串包含formattedGitBranch\[&\]as中,\[\e[0;91m\]

你已经在其他地方正确地完成了它.刚刚在formattedGitBranch中错过了它.