Bashでこれらのシーケンスが外部プロセスまたは関数の標準出力から来る場合、幅が0のシーケンスをPS1にエンコードする方法は?writes-prompt-sequences-to-stdout
プロンプトから複数の色のテキストをエクスポートするにはどうすればよいですか?
PS1='$( writes-prompt-sequences-to-stdout )'
\[
\]
私はbash PS1プロンプトを書くときにbashが正しいプロンプト幅を計算できるように、幅0のシーケンスをラップする必要があることを知っています。
PS1='\[\e[0;35m\]$ \[\e[00m\]'
\[
\]
bashは、プロンプトの幅が2文字にすぎないことを印刷せずに理解します。
これらのシーケンスを外部関数にどのように移動できますか?実行してstdoutに正しいバイトシーケンスを書き込むことを確認できます\[\]$ \[\]
が、これはうまくいきません。私のプロンプトは次のとおりです。render-prompt
PS1='$( render-prompt )'
function render-prompt {
printf '\[\e[0;35m\]$ \[\e[00m\]'
}
printf呼び出しをPS1に移動する働く:
PS1='$( printf '"'"'\[\e[0;35m\]$ \[\e[00m\]'"'"' )'
おそらくbashがPS1文字列をスキャンしているようです。実行前幅0のバイト数を計算します。だから私は印刷されていない[]シーケンスをエンコードしてだましようとしましたが、トリックを正しく無視しました。
PS1='$( printf '"'"'$$$$$'"'"' '"'"'\[\e[00m\]'"'"' )'
私の質問:
\[
\]
PS1を介して呼び出された関数またはバイナリの標準出力にシーケンスを作成するにはどうすればよいですか?
答え1
私はそれについて考えた。 Bash特別な場合\e
、およびPS1 \[
。エスケープされたバイト、バイト、バイトに\]
変換されます。外部コマンドは標準出力にバイトを書き込む必要があります。\e
\[
1
\]
2
1
2
ASCIIによると、「タイトルの開始」と「テキストの開始」をエンコードします。
http://www.columbia.edu/kermit/ascii.html
\
以下は、最初の位置引数のエスケープ文字を正しいバイトに変換するためにprintfを使用する操作の例です。
PS1='$( render-prompt )'
function render-prompt {
printf '\1\033[0;35m\2$ \1\033[00m\2'
}
render-prompt | hexdump -C
00000000 01 1b 5b 30 3b 33 35 6d 02 24 20 01 1b 5b 30 30 |..[0;35m.$ ..[00|
00000010 6d 02 |m.|
00000012
答え2
\1
、\2
およびを正しく計算しました\e
。しかし、シーケンスを生成するより良い、より正確な方法があります。
このprintf
コマンドはFORMATを最初のパラメーターとして使用します。この形式は後続のパラメータを使用します。したがって、関数は次のようによく書くことができます。
render-prompt () { printf "\1%b\2%s\1%b\2" '\e[0;35m' '$ ' '\e[00m'; }
最初のパラメータはであり"\1%b\2%s\1%b\2"
、これが形式です。これはパラメータを含むとの\1
適切で論理的な場所です。 (sは標準文字列を表すエスケープ文字列です。)\2
%b
%b
\
%s
'\e[0;35m'
残りは、および'$ '
で、それぞれ、および'\e[00m'
形式に対応します。 sは前の中かっこを出てしまったのでここに入れました。%b
%s
%b
\e
[