Bash 提示符:在 PROMPT_COMMAND 中使用 \

Bash 提示符:在 PROMPT_COMMAND 中使用 \

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

各种来源(包括这个问题)参考格式化的需要\[\]周围的格式化,以帮助 bash 知道不要用长命令覆盖提示符。

创建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

答案1

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

比较:

$ foo=\[hello\]
$ echo "$foo"
[hello]

对比:

$ foo="\[hello\]"
$ echo "$foo"
\[hello\]

不仅如此:参数扩展(将变量插入到提示字符串中)发生在提示特殊字符扩展之后。因此,将\[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

答案2

PS1 将\[and计算\]为 1 和 2。如果您不想将\[and 的颜色放入 PS1 中,因为它太长,您可以让 PS1 使用已经包含 1 和 2 的变量。如果您使用$'\001'and 将,变量将包含 1如果使用 则包含 2 $'\002'。我已经修改了您的代码以使其按编写的方式工作。

prompt_last_exit_status () {
    PROMPT_LAST_EXIT_STATUS=$?
    if [[ ${PROMPT_LAST_EXIT_STATUS} == "0" ]]; then
        PROMPT_LAST_EXIT_STATUS=
    else
        PROMPT_LAST_EXIT_STATUS=$'\001'$(tput setaf 1)$(tput bold)$'\002'$PROMPT_LAST_EXIT_STATUS
        PROMPT_LAST_EXIT_STATUS+=$'\001'$(tput sgr0)$'\002'
        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

额外信息

您还可以让 PS1 引用在评估 PS1 时将调用的函数。

print_status() {
    printf "\001$(tput setaf 1)$(tput bold)\002$?\001$(tput sgr0)\002"
}
export -f print_status
export PS1='$(print_status) '

注意:导出函数print_status将确保当您 时su,PS1 能够引用它所依赖的函数。另外,请确保任何导出的函数都可以与标准 Bourne shell (sh) 配合使用,因为 git 和 vim 使用这些 shell 并将尝试使用这些函数。

相关内容