PS1 中的重新转义括号

PS1 中的重新转义括号

作为其他的已经指出,颜色代码PS1应该用 和 括起来\[\]以避免它们占用水平空间。我已经添加了必要的代码.bashrc:

highlight()
{
    if [ -x /usr/bin/tput ]
    then
        printf '\['
        tput bold
        printf '\]'
        printf '\['
        tput setaf $1
        printf '\]'
    fi
    shift
    printf -- "$@"
    if [ -x /usr/bin/tput ]
    then
        printf '\['
        tput sgr0
        printf '\]'
    fi
}

highlight_error()
{
    highlight 1 "$@"
}

最后一个函数用于PS1正常和转义命令替换,以便能够根据上一个命令的结果更改字符串:

# Exit code
PS1="\$(exit_code=\${?#0}
highlight_error \"\${exit_code}\${exit_code:+ }\")"

...

if [ "$USER" == 'root' ]
then
    PS1="${PS1}$(highlight_error '\u')"
else
    PS1="${PS1}\u"
fi

问题是转义的括号作为文字输出,所以在运行不存在的命令后我的提示符看起来像这样:

\[\]\[\]127 \[\]user@machine:/path
$

将逃走的人包裹起来highlight_errorprintf %b没有帮助。我怎样才能修复输出,以便我可以使用正常和转义命令替换的函数

答案1

似乎任何转义序列实际上都PS1需要包装在\[and中\],但是如果您调用产生输出的函数或命令,则不需要包装它。

那么为什么不直接移动

"\$(exit_code=\${?#0}
highlight_error \"\${exit_code}\${exit_code:+ }\")"

函数内部的东西,例如

print_error_if_error()
{
    exit_code=$?
    if [ $exit_code -ne 0 ]; then
        highlight_error "$exit_code "
    fi
}

然后我想你可以删除所有的\[东西\]......

highlight()
{
    if [ -x /usr/bin/tput ]
    then
        tput bold
        tput setaf $1
    fi
    shift
    printf -- "$@"
    if [ -x /usr/bin/tput ]
    then
        tput sgr0
    fi
}

highlight_error()
{
    highlight 1 "$@"
}

PS1='$(print_error_if_error)'

# ...

if [ "$USER" = 'root' ]
then
    PS1="${PS1}$(highlight_error '\u')"
else
    PS1="${PS1}\u"
fi

答案2

这个问题使用变量的解决方案$PROMPT_COMMAND。在其中写入一个函数的名称,每次显示新提示之前都会调用该函数。如果您PS1在该函数中进行设置,则可以解决您的问题并在函数中使用颜色命令:

# ... Using your highlight and highlight_error functions ...

prompt(){
    exit_code=${?}
    PS1="\u@\h \$ "
    if [[ $exit_code != 0 ]];then
        PS1="$(highlight_error "($exit_code)") $PS1"
    fi
}

PROMPT_COMMAND="prompt"

相关内容