我在这里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_start
和esc_end
),则无法通过bash将它们正确地评估为“计算转义序列”。我得到了文字方括号。如果然后我也使用Python转义了反斜杠(\\[
和\\]
),那么我将输出未转义的文字(\[
和\]
)。 Bash似乎完全忽略了它们作为计算提示宽度的转义序列。
但是,如果我在PS1命令中删除了反斜杠($(python ~/.bash_prompt.py)
而不是\$(python ~/.bash_prompt.py)
),然后将\[
和\]
作为转义序列放入我的Python脚本中(如esc_start
和esc_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)"'
然后我将转义符(\[
和\]
)添加到了脚本中,现在可以正常使用了! :-)
答案 0 :(得分:1)
Bash first 解释$PS1
中的转义序列,只有之后处理命令替换,等等。
Bash允许通过插入一些反斜杠转义的特殊字符来自定义这些提示字符串,这些特殊字符的解码如下:[...] 字符串解码后,可通过参数扩展,命令替换,算术扩展和引号删除来扩展。[...]
-Bash Reference Manual: Controlling the Prompt
这意味着您的命令打印的任何特殊序列都不会被解释为颜色等。解决方案是使用$PROMPT_COMMAND
来更改$PS1
的值,例如:
PROMPT_COMMAND='PS1=$(python ~/.bash_prompt.py)'