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

実際にすべてのエスケープシーケンスをandPS1にラップする必要があるように見えますが、出力を生成する関数やコマンドを呼び出す場合は、それをラップする必要はありません。\[\]

それでは、ただ動けばいいですか?

"\$(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"

関連情報