Python + Bash提示:如何打印宽度计算包装器?

时间:2018-08-17 19:02:26

标签: python bash colors prompt

我在这里https://github.com/diogobaeder/dotfiles/blob/master/.bash_prompt.py

编写了一个Python脚本来代替“电力线”作为终端提示解决方案。

然后我要做的就是从该脚本的输出中定义提示:

# in my ~/.bashrc
export PS1="\$(python ~/.bash_prompt.py)"

脚本本身运行良好,我得到了所需的命令提示符;但是,由于这里没有样式的包装,所以终端(无论使用哪种GUI终端程序)都无法正确计算提示宽度,并且当我在提示后键入字符时,它最终没有包装它们首先转到新行,完全覆盖提示。

现在,我知道在样式化bash提示时,我需要使用\[\]来转义样式代码,以便bash考虑到它们是转义序列并正确计算宽度。但是,如果我在Python脚本中将它们作为样式的包装器(请参见esc_startesc_end),则无法通过bash将它们正确地评估为“计算转义序列”。我得到了文字方括号。如果然后我也使用Python转义了反斜杠(\\[\\]),那么我将输出未转义的文字(\[\])。 Bash似乎完全忽略了它们作为计算提示宽度的转义序列。

但是,如果我在PS1命令中删除了反斜杠($(python ~/.bash_prompt.py)而不是\$(python ~/.bash_prompt.py)),然后将\[\]作为转义序列放入我的Python脚本中(如esc_startesc_end),然后bash认为它们是正确的转义符,并最终按预期换行(即,当我经过右边界时,按预期换行)。但是,与此有关的问题是,从.bashrc的PS1定义中删除此反斜杠会使脚本在每个终端会话中仅运行一次,而不是在每个提示行中都运行-例如,如果我在Git工作树,我从一个分支更改为另一个分支,命令完成后它不会立即显示新分支,而是显示了旧分支。

让我举一些我的意思的例子,您可以在不需要我的Python脚本的情况下尝试自己的.bashrc

PS1="\[\033[31m\]\u@\h\[\033[0m\]$ " # This wraps lines correctly
PS1="\033[31m\u@\h\033[0m$ " # This makes the line overwrite the prompt

那么,关于如何应对bash并使其在通过Python脚本打印时正确理解\[\]序列的任何想法,同时仍然保持脚本在每个命令提示符下运行?或者,如果这是bash的局限性,还有另一种方法可以迫使它在到达终端窗口的右边界时将行换行?

谢谢! 迪奥戈

[编辑] 解决方案(感谢Grisha Levit!):

现在这是我的bashrc行:

PROMPT_COMMAND='PS1="$(python ~/.bash_prompt.py)"'

然后我将转义符(\[\])添加到了脚本中,现在可以正常使用了! :-)

1 个答案:

答案 0 :(得分:1)

Bash first 解释$PS1中的转义序列,只有之后处理命令替换,等等。

  

Bash允许通过插入一些反斜杠转义的特殊字符来自定义这些提示字符串,这些特殊字符的解码如下:[...]   字符串解码后,可通过参数扩展,命令替换,算术扩展和引号删除来扩展。[...]

-Bash Reference Manual: Controlling the Prompt

这意味着您的命令打印的任何特殊序列都不会被解释为颜色等。解决方案是使用$PROMPT_COMMAND来更改$PS1的值,例如:

PROMPT_COMMAND='PS1=$(python ~/.bash_prompt.py)'