1

2回の呼び出しなしでbashプロンプトのテキストに色を付ける効率的な方法はありますか?

PS1のカスタマイズについては、周りにたくさんのリソースがあります。ここでの重要なポイントは次のとおりです。

  • カスタム関数を呼び出してテキストを生成し、カスタムテキストを生成することができます
  • このような関数がカスタムカラーコードを出力する可能性があります
  • ワードラップを機能させるには、印刷されないテキスト(カラーコードなど)にマークを付ける必要があります
  • カスタム関数がそのマーキングを行うことはできません。

私は最後の点で間違っているかもしれません、そして方法があれば、それはこれを完全に解決するでしょう。

これは、私がいじくり回しているものとトポロジー的に類似している、単純化されたやや不自然な例です。generate_textstdoutで「OK」または1ワードのメッセージを生成する外部コマンド(それを呼び出します)があります。また、何も放出しない場合があります。これらの3つの状態をプロンプトに表示する必要があります。何も出力しない場合は、プロンプトをそのままにします(user@hostname:path$); OKが表示される場合は、プロンプトの前に緑色の「OK」を付けます。どちらかといえば、そのテキストを赤で入力してください。

私の現在の解決策は、generate_textを呼び出し、そのテキストを出力するか、それに基づいてカラーコードを出力するカスタム関数を用意し、その関数を2回呼び出すことです。

generate_prompt()
{
    txt=`generate_text`
    [ -z "$txt" ] && exit # The empty case. Produce nothing.
    $1 && echo "##$msg## " || case $msg in
        'OK') echo -e '\e[1;32m'; ;; # Green for OK
        *) echo -e "\e[1;31m"; ;; # Red for anything else
    esac
}
PS1='\[$(generate_prompt false)\]$(generate_prompt true)\[\e[0m\]'$PS1

これは、generate_textを2回呼び出して、同じ文字列を返すと想定する必要があることを意味します(通常はそうですが、理論的には、2つの呼び出しの間で状態が変わる可能性があります)。これはやや無駄だと思います。同じ関数内から非印刷カラーコードとテキストの両方を出力する便利な方法はありますか?

4

2 に答える 2

3

PROMPT_COMMANDを使用して必要なすべての値を計算し、プロンプトでそれらを使用できます。

generate_prompt() {
  color="" message=""
  txt=$(generate_text)
  [[ -z $txt ]] && return

  message="##$txt##"
  [[ $txt == OK ]] && color=$'\e[1;32m' || color=$'\e[1;31m'
}
PROMPT_COMMAND=generate_prompt
PS1='\[$color\]$message\[\e[0m\]'$PS1

PROMPT_COMMANDは、xtermタイトルを設定するようにすでに構成されている場合があることに注意してください。その場合は、代わりに追加できます。

于 2013-01-31T23:19:45.280 に答える
3

これは文書化されていないため、おそらく良い解決策ではありませんが、機能しているように見えます。これは、\001から\002文字の間のテキストがプロンプト文字列に表示される文字数にカウントされないことを示す、bashプロンプトの内部知識を使用します。

generate_prompt()
{
    local txt=$(generate_text)
    case "$txt" in
        '') ;;
        OK) echo -e "\001\e[1;32m\002 $txt \001\e[0m\002"; ;; # Green for OK
         *) echo -e "\001\e[1;31m\002 $txt \001\e[0m\002"; ;; # Red for anything else
    esac
}
PS1='$(generate_prompt)'$PS1

プロンプト文字列を展開するbashソースには、上記のソリューションを定式化するために使用された次のコメントが含まれています。

/* Current implementation:
    \001 (^A) start non-visible characters
    \002 (^B) end non-visible characters
   all characters except \001 and \002 (following a \001) are copied to
   the returned string; all characters except those between \001 and
   \002 are assumed to be `visible'. */ 
于 2013-01-31T23:39:55.280 に答える