Bash 提示:在 PROMPT_COMMAND 中使用 \[ 和 \]

Dav*_*ord 5 bash prompt bashrc

我正在处理 bash 提示。我也在尝试智能地创建提示,以便它易于阅读和维护。这意味着没有一个巨大的export PS1.

各种来源(包括这个问题)引用需要\[\]周围的格式,以帮助庆典知道不能覆盖的提示与长命令。

创建PROMPT_LAST_EXIT_STATUS字符串时,目的是将最后一个命令 ( $?)的退出状态显示为红色,或者不显示(如果$?为 0)。这有效,但文字[s 和]s 出现在提示中,并且长命令问题仍然存在。这可能是某个地方的转义问题,但我还没有找到。

意想不到的方括号

以下代码在~/.bashrc.

prompt_last_exit_status () {
PROMPT_LAST_EXIT_STATUS="${?}";
if [[ ${PROMPT_LAST_EXIT_STATUS} == "0" ]];
then
    PROMPT_LAST_EXIT_STATUS=
else
    PROMPT_LAST_EXIT_STATUS=\[$(tput setaf 1)$(tput bold)\]${PROMPT_LAST_EXIT_STATUS}
    PROMPT_LAST_EXIT_STATUS+=\[$(tput sgr0)\]
    PROMPT_LAST_EXIT_STATUS+=" "
fi;
}


prompt_command () {
    prompt_last_exit_status
}
export PROMPT_COMMAND=prompt_command

PS1="\${PROMPT_LAST_EXIT_STATUS}"
PS1+="\[$(tput setaf 6)$(tput bold)\]\w"
PS1+="\[$(tput sgr0)\] \$ \[$(tput sgr0)\]"
export PS1
Run Code Online (Sandbox Code Playgroud)

god*_*eek 3

您对 的分配PROMPT_LAST_EXIT_STATUS没有被引用,因此您没有将\[and\]放入字符串中,您只是将[and ](因为\s 被视为转义字符)。

比较:

$ foo=\[hello\]
$ echo "$foo"
[hello]
Run Code Online (Sandbox Code Playgroud)

对比:

$ foo="\[hello\]"
$ echo "$foo"
\[hello\]
Run Code Online (Sandbox Code Playgroud)

不仅如此:参数扩展(将变量插入到提示字符串中)发生在提示特殊字符扩展之后。因此,将\[and放入变量\]PROMPT_LAST_EXIT_STATUS是行不通的,因为到$PROMPT_LAST_EXIT_STATUS扩展时,\[and\]不再特殊。一个可行的替代方案是将颜色设置变为无条件,例如:

prompt_last_exit_status () {
    PROMPT_LAST_EXIT_STATUS="${?}"
    if [[ ${PROMPT_LAST_EXIT_STATUS} == "0" ]]
    then
        PROMPT_LAST_EXIT_STATUS=
    else
        PROMPT_LAST_EXIT_STATUS+=" "
    fi
}

prompt_command () {
    prompt_last_exit_status
}
export PROMPT_COMMAND=prompt_command

PS1="\[$(tput setaf 1)$(tput bold)\]\${PROMPT_LAST_EXIT_STATUS}\[$(tput sgr0)\]"
PS1+="\[$(tput setaf 6)$(tput bold)\]\w"
PS1+="\[$(tput sgr0)\] \$ \[$(tput sgr0)\]"
export PS1
Run Code Online (Sandbox Code Playgroud)