自定义 Bash 提示正在覆盖自身

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19092488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 08:06:37  来源:igfitidea点击:

Custom Bash prompt is overwriting itself

bashcommand-promptgentoo

提问by A.D.

I'm using custom bash prompt to show git branch.

我正在使用自定义 bash 提示来显示 git branch。

Everything is in /etc/bash/bashrc:

一切都在/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='\[3[01;34m\] \[3[0;91m\]$(formattedGitBranch) $\[3[00m\] '
# color is set inside function
PS1='\[3[01;34m\] $(formattedGitBranch) $\[3[00m\] '

Problem is that when I set color for $_branchin the function, my prompt will be overwritten when EOL is reached:

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

mmmmmmmmmmmmp/rainyday.js (master) $ mmmmmmmm

mmmmmmmmmmmmp/rainyday.js (master) $ mmmmmmmm

Tried all possible variants tput, printf, $''notation.

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

I solved the problem by setting the colour only in PS1:

我通过仅在PS1以下位置设置颜色解决了这个问题:

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

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

But..

但..

  1. I would like to know why it is overwriting my prompt
  2. How to fix this issue when function is used
  1. 我想知道为什么它会覆盖我的提示
  2. 使用函数时如何解决此问题

I'm using Gentoo Linux. GNU bash, verze 4.2.37(1)-release (i686-pc-linux-gnu)

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

回答by A.D.

1) I would like to know why it is overwriting my prompt

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

Because every non-printable characters have to be escaped by \[and \]otherwise readlinecannot keep track of the cursor position correctly.

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

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

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

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

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

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

2) How to fix this issue when functionis used

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

If you want to set colours inside a functionwhose output is used in PSyou have two options.

如果要在使用function其输出的a 中设置颜色,PS您有两个选择。

  • Either escape the whole function call:

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

  • Or replace the non-printing Escapesequences inside echo. That is, replace:

    \[and \]with \001\002

    (thanks to user grawity!)

  • echo -eis not awareof bash's \[\]so you have to substitute these with \001& \002ASCII control codes to delimit non-printable chars from printable:

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

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

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

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

    \[\]\001\002

    (感谢用户的成长!)

  • echo -e不知道bash 的,\[\]因此您必须用\001& \002ASCII 控制代码替换这些代码,以将不可打印的字符与可打印的字符分隔开:

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

回答by anishsane

Strings like \e[0;91mneeds additional quoting, to prevent bash from calculating its length.

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

Enclose these strings from formattedGitBranchin \[& \]as, \[\e[0;91m\]

将这些字符串从formattedGitBranchin \[& \]as括起来,\[\e[0;91m\]

You have done it correctly in other places. Just missed it in formattedGitBranch.

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

回答by SUMIT KUMAR SINGH

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 :

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

After

后

few examples :

几个例子:

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

Refer Link : syntax for bash PS1

参考链接:bash PS1 的语法