ターミナルでサポートされているANSIエスケープコードをプログラムで検出する

ターミナルでサポートされているANSIエスケープコードをプログラムで検出する

ANSI コードを使用するシェル スクリプトを試していたところ、何らかの理由で端末/OS に応じて異なるエスケープ コードがサポートされていることがわかりました。

場合によっては、予期せず解析されていないゴミのダンプを取得することがあります。これは、いくつかの場所でこれらが同じことを意味すると読んだにもかかわらず、私のターミナル (Mac OS 上) が使用されているエスケープ コードをサポートしていないことを意味していると想定しています。

27 = 033 = 0x1b = ^[ = \e

検索してみるとスラッシュエスケープのサポートの検出に関するこの質問

選択された回答は$TERM検出する値を嗅ぎます

case $TERM in
  (|color(|?))(([Ekx]|dt|(ai|n)x)term|rxvt|screen*)*)
    PS1=$'\e\]0;$GENERATED_WINDOW_TITLE\a'"$PS1"
esac

しかし、それがどれだけ信頼できるものなのか疑問です。

エスケープ コードのサポートを確認する標準的な方法はありますか (主に Bash の場合)、それともそのスクリプトはごく一般的なものでしょうか。

  • あるいは、最も広範なサポートを「保証」するためにどのようなエスケープ コードを使用できますか?
  • echo 拡張 -e はどうでしょうか?
  • 移植性/可用性/配布に関する一般的なベストプラクティスは何ですか?スクリプト制御コードを使用または参照するものですか?

これは読み物としても面白い情報を探している人のために。

答え1

具体的な操作をお考えですか?

使用例はこちら目立つモード多くの端末では、次のようなはっきりとした目に見える結果が得られます。

tput smso; echo hello, world; tput rmso

ツールは環境変数tputの値を使用して、$TERMどのエスケープシーケンスを出力するかを決定します(存在する場合)。たとえば、

TERM=xterm
( tput smso; echo hello, world; tput rmso ) | hexdump -C
00000000  1b 5b 37 6d 68 65 6c 6c  6f 2c 20 77 6f 72 6c 64  |.[7mhello, world|
00000010  0a 1b 5b 32 37 6d                                 |..[27m|

TERM=dumb
( tput smso; echo hello, world; tput rmso ) | hexdump -C
00000000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a           |hello, world.|

興味深い特徴の組み合わせは、man 5 terminfoいくつか例を挙げると以下の通りです。

  • 注目点:smsoそしてrmso
  • 下線:smulおよびrmul
  • 瞬き(はい!):blink
  • ダブルワイド:swidmそしてrwidm
  • 逆行する:rev
  • すべてキャンセル:sgr0

太字のテキストを書きたいが、端末がそれを理解できる場合のみ、次のようなスニペットが機能します。

boldOn=$(tput smso)
boldOff=$(tput rmso)
# ...
printf "%s%s%s\n" "$boldOn" 'This message will be in bold, when available' "$boldOff"

答え2

実際には、DEC 端末 (および xterm を含むそのクローンとエミュレーション) の機能について問い合わせることは可能ですが、個々のエスケープ シーケンスのサポート (またはその完全性) については問い合わせることができません。UNIX は一般にこの機能を使用せず、termcap/terminfo データベース (これも癖を文書化します) に依存しています。

参考までに、シーケンスは DA (「デバイス属性」、ANSI 標準) と DECID (「端末の識別」、DEC プライベート) です。

関連情報