印刷されないエスケープシーケンス:いつ?

印刷されないエスケープシーケンス:いつ?

私は最近、端末で色をたくさん扱っていたので、エスケープシーケンスを使用しました。私はBashのマンページの関連セクションとWebから多くの有用なページを読んだ。

たとえば、素敵でカラフルなBashプロンプトなど、私が望むほとんどを手に入れました。つまり、「非印刷エスケープシーケンス」文字を使用する必要がある場合(または使用する必要がある場合)はまだ少し混乱します。彼らは\[とです\]

もし私がいいえプロンプトを定義するときにPS1でそれを使用すると、プロンプトが正しく表示されません。使用すると、すべてが大丈夫です。いいね

しかし、PS1の外では同じように動作しないようです。たとえば、スクリプトを読みやすくするために、$RGB_PURPLE単純な関数で設定される変数を定義しましたc8_rgb()。最終結果は、変数\[\e[01;38;05;129m\]に太い紫色の前景色をオンにする値が含まれていることです。

PS1でこの変数を使用すると、期待どおりに機能します。通過またはprintf使用すると、echo -e「半分」が機能します。このコマンドprintf "${RGB_PURPLE}TEST${COLOR_CLR}\n"COLOR_CLRテキスト属性をリセットするエスケープシーケンスはどこにありますか?)は次のように表示されます。\[\]TEST\[\]ここで、最初\[と最後を除くすべての項目は\]紫色で表示されます。

なぜ違いがありますか?これらの括弧が印刷されているが端末で処理されないのはなぜですか?他の方法で印刷する場合と同様に、プロンプトの一部として印刷するときにも同じように処理されたことがわかりました。私はこの変化を理解していません。

経験的に見ると、これらの役割は〜しなければならないプロンプトの定義に使用されますが、してはいけない他のほとんどすべての状況で使用できます。これにより、c8_rgb()エスケープシーケンスの生成と出力を処理するために上記のような汎用関数を使用することは困難です。関数は、その結果がプロンプト構成にあるのか、それとも別の場所にあるのかを知る方法がないからです。

1つのより速い関連質問:エスケープシーケンス出力に関して本質的に同じですかecho -eprintf私は通常printfを使用していますが、他のものよりも好む理由がありますか?

この明らかなニュアンスを説明できる人はいますか?端末でエスケープシーケンス(通常の色のみ)を使用するときに知っておくべき他の奇妙なことはありますか?ありがとうございます!

答え1

$ PS1で印刷されない文字を使用する場合は、「印刷されないエスケープシーケンス」が必要です。コマンドラインを編集するときに画面を正しく更新するには、bashがカーソルの位置を知る必要があるためです。 Bashは$ PS1プロンプトの文字数(カーソルがある列番号)を計算してこれを行います。

ただし、印刷されていないシーケンスを$ PS1に入れるとカウントが正しくなくなり、コマンドラインを編集すると行がめちゃくちゃになることがあります。したがって、埋め込まれたバイトを計算しないことを示すために\[フラグが導入されました。\]

答え2

私は以下を使用して十分な解決策を見つけました:8進数完全なエスケープシーケンスであり、区切り文字のreadline形式を使用します。 PS1、echo -e、printf はすべて、まったく同じ文字列を使用して、このように正しい操作を実行します。私はこれをOSXのBash 4とLinuxのBash 3でテストしました。

ここでは、\001と\002のアイデアを得ました。https://superuser.com/questions/301353/escape-non-printing-characters-in-a-function-for-a-bash-prompt?rq=1

例:

$ TextGreen='\001\033[0;32m\002'
$ TextReset='\001\033[0m\002'
$ SomeString="${TextGreen}prompt_stuph${TextReset} \$ "
$ #
$ # now all of the following work as expected
$ #
$ PS1="$SomeString"
$ printf "$SomeString"
$ echo -e "$SomeString"

答え3

同様に␛[01;38;05;129m、最初の文字はターミナルエスケープシーケンスであるASCIIエスケープ文字(U + 0027)です。これは、端末に色129で太く点滅するテキストの表示を開始するように指示する。エスケープ文字(inside、in、in、およびin)\eのbash構文。$'…'PS1echo -eprintf

\[ターミナルエスケープシーケンスではなく、\]bashプロンプトエスケープシーケンスです。端末に送信されず、bashによって解釈されます。彼らの目的は、その間にある文字が印刷されない文字であることをbashに伝えることです。したがって、プロンプトの幅は実際には含まれていない文字の数です\[…\]。 Bashは行エディタでカーソル位置を計算するためにプロンプ​​トの幅を知る必要があります。

\[…\]関数がプロンプト文字列の外部で使用されることを意図している場合は、その関数を出力しないでください。プロンプト文字列におよびを直接含めます\[\]

関連情報