Python + bash 提示:如何打印width calculation wrappers?

Python + bash prompt: how to print width calculation wrappers?

我在这里写了一个 Python 脚本来替换 "powerline" 作为我自己的终端提示解决方案:https://github.com/diogobaeder/dotfiles/blob/master/.bash_prompt.py

然后我所做的就是根据该脚本的输出定义提示:

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

脚本本身运行良好,我得到了我想要的命令提示符;但是,由于我放在那里的样式没有换行,终端(无论我使用哪个 GUI 终端程序都无关紧要)无法正确计算提示宽度,并且当我在提示后键入字符时,它最终不会换行首先换行,完全覆盖提示。

现在,我知道在对 bash 提示进行样式化时,我需要使用 \[\] 转义样式代码,以便 bash 考虑到它们'重新转义序列并正确计算宽度。但是,如果我将它们作为我的样式的包装器放在我的 Python 脚本中(参见 esc_startesc_end),我无法让它们被 bash 正确评估作为 "calculation escape sequences",我得到的是文字方括号。如果我然后在 Python 中转义反斜杠(\[\]),那么我会输出未转义的文字(\[\])。 Bash 似乎完全忽略它们作为计算提示宽度的转义序列。

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

让我举一些例子来说明我的意思,您可以自己尝试 .bashrc 而无需我的 Python 脚本:

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

所以,关于如何处理 bash 并使其在 Python 脚本打印时正确理解 \[\] 序列的任何想法,同时仍然为每个命令提示符保留脚本 运行ning?或者,如果这是 bash 中的限制,是否有另一种方法可以强制它在到达终端 window 的右边界时换行?

谢谢! 迪奥戈

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

现在这是我的 bashrc 行:

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

然后我将转义符(\[\])重新添加到我的脚本中,现在它完美运行了! :-)

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

Bash allows these prompt strings to be customized by inserting a number of backslash-escaped special characters that are decoded as follows [...] After the string is decoded, it is expanded via parameter expansion, command substitution, arithmetic expansion, and quote removal [...]

--Bash Reference Manual: Controlling the Prompt

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

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