web-dev-qa-db-ja.com

非印刷エスケープシーケンス:いつ?

最近、私はターミナルの色で、したがってエスケープシーケンスでもたくさん遊んでいます。 Bashのマンページの関連部分と、ネット上の多数の役立つページを読みました。

私は働きたいもののほとんどを持っています。たとえば、素敵な色のBashプロンプト。とはいえ、「非印刷エスケープシーケンス」文字をいつ使用する必要があるか(または使用する必要があるか)については、まだ多少混乱しています。それらは\[\]になります。

私がしないでください私のプロンプトを定義するときにPS1でそれらを使用すると、私のプロンプトは間違いなく正しく表示されません。私がそれらを使用する場合、すべてが大丈夫です。良い。

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

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

なぜ違いがあるのですか?これらのブラケットが端末で処理される代わりに印刷されるのはなぜですか?プロンプトの一部として印刷する場合は、他の方法で印刷する場合と同じように扱われることを期待していました。変化がわかりません。

経験的に、これらの文字必須はプロンプト定義内で使用されているようですが、使用すべきではない他のほとんどすべての場合に使用されます。これにより、前述のc8_rgb()関数のような一般的な関数を使用して、エスケープシーケンスの生成と出力を処理することが困難になります。これは、関数が結果がプロンプト構成にあるか他の場所にあるかを認識できないためです。

そして、簡単な関連する質問:echo -eprintfは、エスケープシーケンスの出力に関して本質的に同じですか?私は通常printfを使用しますが、一方を他方よりも優先する理由はありますか?

誰かがこの明らかな微妙な違いを説明できますか?ターミナルでエスケープシーケンス(通常は色のみ)を使用するときに注意する必要がある他の奇妙な点はありますか?ありがとう!

7
JetpackJohn

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

ただし、印刷されないシーケンスを$ PS1に配置すると、そのカウントが間違っており、コマンドラインを編集すると行が混乱する可能性があります。したがって、\[および\]マーカーを導入して、囲まれたバイトをカウントしないことを示します。

6
wurtel

全体でoctalエスケープシーケンスを使用し、区切り文字のreadline形式を使用することで、十分な解決策を見つけました。 PS1、echo -e、printfはすべて、この方法でまったく同じ文字列で正しいことを行います。これをOSXのBash4とLinuxのBash3でテストしました。

ここでの回答から\ 001と\ 002のアイデアを得ました: https://superuser.com/questions/301353/escape-non-printing-characters-in-a-function-for-a-bash -プロンプト?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
Kevin Olree

␛[01;38;05;129mのようなもの(最初の文字はASCIIエスケープ文字(U + 0027))は、端末のエスケープシーケンスです。これは端末に表示を開始するように指示します。太字で点滅する129色のテキスト。\eはエスケープ文字のbash構文です($'…'内、PS1内、echo -e内、およびprintf内) 。

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

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