自定义Bash提示会覆盖自己

时间:2013-09-30 10:57:25

标签: bash command-prompt gentoo

我正在使用自定义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\] '

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

mmmmmmmmmmmmp/rainyday.js (master) $ mmmmmmmm

尝试了所有可能的变体tputprintf$''表示法。

我通过仅在PS1

中设置颜色来解决问题

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

但是...

  1. 我想知道为什么要覆盖我的提示
  2. 如何在使用功能时解决此问题
  3. 我正在使用Gentoo Linux。 GNU bash, verze 4.2.37(1)-release (i686-pc-linux-gnu)

3 个答案:

答案 0 :(得分:44)

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

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

  

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

     

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

     

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

     

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

2)如何在使用function时解决此问题

如果您想在function内设置颜色,PS的输出用于PS1='\[ $(formattedGitBranch) \] ',您有两种选择。

  • 要么转义整个函数调用:

    echo

  • \[内的replace the non-printing Escape个序列。也就是说,替换:

    \]\001\002 echo -e

    (感谢user grawity!)

  • bash \[ \]
  • \001 is not aware所以你必须用\002& function formattedGitBranch { echo -e "\001\e[0;91m\002 ($_branch)"; } ASCII控制代码,用于将不可打印的字符与可打印的字符分隔开来:

    PS1='$(formattedGitBranch) '   {{1}}

答案 1 :(得分:10)

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

将这些字符串括在formattedGitBranch中的\[& \] as,\[\e[0;91m\]

您已在其他地方正确完成。刚刚在formattedGitBranch中错过了它。

答案 2 :(得分:0)

你必须在[\和/]中处理不可打印的字符,否则你可能会把光标放在命令提示符的顶部,就像问题本身一样,所以我找到了一些东西而只是分享它: -

在PS1输出后获取光标在同一行:

After

几个例子:

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

参考链接:syntax for bash PS1