【问题标题】:Custom Bash prompt is overwriting itself自定义 Bash 提示正在覆盖自身
【发布时间】:2013-09-30 10:57:24
【问题描述】:

我正在使用自定义 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时我的提示将被覆盖:

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

我通过只在PS1中设置颜色解决了这个问题:

但是..

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

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

【问题讨论】:

标签: bash command-prompt gentoo


【解决方案1】:

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

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

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

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

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

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

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

如果您想在function 中设置颜色,其输出用于PS,您有两种选择。

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

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

  • replace the non-printing Escape 内的echo 序列。即替换:

    \[\]\001 \002

    (感谢user grawity!)

  • echo -e is not aware 的 bash 的 \[ \] 所以你必须用 \001\002 ASCII 控制代码来替换这些字符,以将不可打印字符与可打印字符分隔:

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

【讨论】:

  • 我使用 \[ 而不使用 \] 并且它导致了与 OP 类似的问题。谢谢。
  • 如果不是很明显:除了确保所有不可打印的字符都包含在 \[ \] 中,您还必须确保所有 可打印 字符没有包装。不正确地包装可打印字符会导致与无法包装不可打印字符相同类型的问题。
  • 我没有使用echo -e 作为提示字符串,但我遇到了同样的问题。使用\001\002 而不是\[\] 也解决了它。非常感谢!!现在已经困扰我一年多了。
  • link 还建议使用十六进制版本 \x01\x02 来避免“bash 错误导致它在处理八进制转义”。
【解决方案2】:

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

formattedGitBranch 中的这些字符串包含在\[\] 中,如\[\e[0;91m\]

你在其他地方做得正确。只是在 formattedGitBranch 中错过了它。

【讨论】:

  • 不,我省略了它,因为我的 bashrc 中有一条说明它不起作用。 (我的)echo -e 无法处理 \[ \] i.stack.imgur.com/4T0VQ.png 但您可能是正确的,需要关闭,但我不知道如何在 echo 中关闭它。
  • echo 只是为PS1 的值生成字符。 bash shell 将在删除 \[\] 后处理提示的实际显示。
  • @anishsane 你的意思是:\[ $(formattedGitBranch) \]?我对你的最后一句话感到非常困惑“只是错过了它in formattedGitBranch。”以为你在谈论echo -e ...这是INside formattedGitBranch函数。
  • ^^ 我还没有真正在 PS1 中尝试过echo -e,但我怀疑这是唯一缺少的东西。 \[$(formattedGitBranch)\] 也值得一试。
  • downvoter,请让我知道错误是什么,以便我纠正和学习......
【解决方案3】:

您必须注意 [\ 和 /] 内的不可打印字符,否则您可能会将光标放在命令提示符的顶部,因为它本身是共享的,所以我找到了一些东西并分享了它:-

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

几个例子:

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

参考链接:syntax for bash PS1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多