Bashプロンプト(PS1変数)で、プロンプトにテキストを追加する可能性のある関数を呼び出しています:export PS1="\u@\h \$(my_function) \$ "
ただし、プロンプトの関数には、関数の出力に基づいて変化するANSIカラーコードが含まれています(赤の場合もあれば、緑の場合もあります)。 PS1変数に「\[
」を追加すると、これらのコードは非印刷としてエスケープされますが、関数でecho
を実行すると、「\[
」が文字通りプロンプトに出力されます。 。
Bashプロンプトで使用するために関数内からこれらのANSIカラーコードをエスケープするにはどうすればよいですか?
readlineライブラリは、\001
および\002
(ASCII SOHおよびSTX )を印刷不可として受け入れますテキスト区切り文字。これらは、readlineを使用するすべてのアプリケーションでも機能します。
bashソースコードのlib/readline/display.c:243
から:
243 /* Current implementation:
244 \001 (^A) start non-visible characters
245 \002 (^B) end non-visible characters
246 all characters except \001 and \002 (following a \001) are copied to
247 the returned string; all characters except those between \001 and
248 \002 are assumed to be `visible'. */
bash固有の\[
および\]
は、実際には\001
および\002
に変換されます。 y.tab.c:7640
。
注:bashのprintf
またはecho -e
を使用し、テキストに\001
または\002
数値の直前で、bashバグが発生し、8進数のエスケープを処理するときに1桁を食べすぎてしまいます。つまり、\00142
は、正しい8進数01(ASCII)が続く)ではなく、8進数014(ASCII "2")が続く)として解釈されます。 「42」)。このため、代わりに16進数バージョン\x01
および\x02
を使用してください。
これが素晴らしい完全な答えです。\001などがどこに行かなければならないかを理解するために、私はもっと多くの掘り下げをしなければなりませんでした。お役に立てれば。
# Color Prompt for git
reset=$(tput sgr0)
boldgreen=$(tput setaf 2)$(tput bold)
cyan=$(tput sgr0)$(tput setaf 6)
boldred=$(tput setaf 1)$(tput bold)
boldwhite=$(tput setaf 7)$(tput bold)
boldyellow=$(tput setaf 3)$(tput bold)
PARENCLR=$'\001\e[0;36m\002'
BRANCHCLR=$'\001\e[1;33m\002'
alias branchname="git branch 2>/dev/null | grep '*' | sed 's/* \(.*\)/ ${PARENCLR}(${BRANCHCLR}\1${PARENCLR}\)/'"
GIT_STATUS='$(branchname)'
Prompt_CHAR="\$"
PS1="\[$boldgreen\]\u\[$cyan\]::\[$boldred\]\h \[$cyan\]{\[$boldwhite\].../\W\[$cyan\]}\[$reset\]$GIT_STATUS\[$reset\]$Prompt_CHAR "
ここで設定した方法では、gitブランチの括弧は、gitブランチにいる場合にのみ表示され、それ以外の場合は空白になります。
grawityの回答 に基づいて、以下はANSI制御シーケンスをASCII SOH
(^A
)およびSTX
で囲みます。 (^B
)これはそれぞれ\[
および\]
と同等です:
function readline_ANSI_escape() {
if [[ $# -ge 1 ]]; then
echo "$*"
else
cat # Read string from STDIN
fi | \
Perl -pe 's/(?:(?<!\x1)|(?<!\\\[))(\x1b\[[0-9;]*[mG])(?!\x2|\\\])/\x1\1\x2/g'
}
次のように使用します。
$ echo $'\e[0;1;31mRED' | readline_ANSI_escape
または:
$ readline_ANSI_escape "$string"
ボーナスとして、関数を複数回実行しても、すでにエスケープされている制御コードは再エスケープされません。