{}がTerminal.appにäåとして表示され始めるのはなぜですか?

{}がTerminal.appにäåとして表示され始めるのはなぜですか?

CentOS 7.9を実行していますが、今日端末に奇妙な文字が表示されます。一部の文字は大丈夫に見えますが、一部の記号は英語ではなく文字として表示されます。たとえば、次の内容でテキストファイルを作成しました。

!@#$%^&*()_+{}

開いてみると上に書いたのと同じですねvinanoしかし、ターミナルでは次のように見えます。

$ cat chars.txt 
!É#$%Ü&*()_+äå

$ od -An -vtx1 < chars.txt
 21 40 23 24 25 5e 26 2a 28 29 5f 2b 7b 7d 0a

この奇妙な文字は私が入力している間でもどこにでもあります。そのマシンは今日までも素晴らしい作品です。私考えるバイナリをダウンロードしcurlてパラメータを使用することを忘れた後、これが起こりました-O。他のユーザーで再起動してログインしても役に立ちませんでした。私のロケール設定は次のとおりです。何を探すべきか分からない。私が使っているシェルはBashバージョン4.2であり、特別なことはありません。

$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

編集:サーバーのシェルがbash 4.2であると言う方が正確です。私はTerminal.appを使ってmacOS Big Surにログインしています。

答え1

これにより、xtermターミナルエミュレータ(バージョン366)を使用して再現できます。

$ printf '\e[?42h\e(H'; cat chars.txt; printf '\e(B\e[?42l'
!É#$%Ü&*()_+äå

どこ:

他の人は設定をキャンセルします。

端末を定常状態に復元するには、ncursesコマンドを使用することもできますreset。ここで私は\ecそれが送信するシーケンスを見つけました(たとえば、rs1送信された/関数はデフォルトの文字セットを復元する役割を果たします)。reset_1stringtput rs1

通常表示される理由は、コマンドセッションで実行し、後で結果を見ると、コマンドセッションに切り替えた後に実際にシーケンスが送信されることがわかりnanoます(G0の場合はUS-ASCII選択)。nanoscripttypescriptnano\e(B代替画面おそらく、\e[?1049hいくつかのncurses初期化の一部としてnano代替画面から出ると、元の文字セットが復元されます。

今、\e(H誤ってバイナリファイルからシーケンス(0x1b 0x28 0x48バイトシーケンス)を取得するのは妥当です。平均して、1,600万個のランダムな3バイトシーケンスの1つがこのようになります。ここでいくつか見つかりました。

$ LC_ALL=C grep -rFl $'\e(H' /lib
/lib/x86_64-linux-gnu/libicui18n.so.66.1
/lib/x86_64-linux-gnu/ceph/libceph-common.so.2
[...]

例えば。

しかし、\e[?42h6バイト(48ビット)シーケンスが偶然に発見される可能性ははるかに少ない(280兆6バイトシーケンスの1つ)。さらに、\e(H端末にダンプしたランダムバイナリにこれらのファイルを順番に保存してください。

しかし、xtermCentOS7では以前のバージョン(295)です。このリリースでは、\e[?42hISO2022処理のためにシーケンスを有効にする必要はありません。このバージョンではxterm、、、\e(H1 つだけで動作を得ることができます。それが変わったバージョン297では2013年9月発売。これは、最近のシステムよりもCentOS7またはその時代のすべてのシステムでこの現象が発生する可能性が高い理由を説明しています。

指摘したように、ワークステーションはCentOSではなくmacosを実行しています。 macosは以前のバージョンxterm2692021年基準Terminal.app)、実際に使用している端末エミュレータに以前と同じバグがあることを明確にしてください。 。xtermxterm

昔は(今までxterm 182私はそれが変更されたと思います)、バイナリを端末にダンプするときのもう一つの一般的な問題は、次に切り替えることです。特殊文字と線画セット0x0eバイト(SO/^N制御文字)が端末に送信される場合。SOそれでもG1セットに切り替わりますが、G1セットは次に初期化されます。線画セット。今日はシーケンスを送信して(\e(0選択線画セットG0の場合:

$ printf '\e(0 blahblah \e(B\n'
 ␉┌▒␤␉┌▒␤

ASCIIで^N/を使用して元の動作に戻ることができます。^O線画セット注文として\e)0

再起動しても役に立たない理由は、エスケープシーケンスの影響を受けるのがターミナルエミュレータであることを覚えておいてください。ターミナルエミュレータで入力したシステムを再起動してもssh役に立ちません。実行中のシステムを再起動するとxterm便利ですが、その端末エミュレータを再起動するか、上記のコマンドをreset端末で実行することもできます(エスケープシーケンスを端末エミュレータに送信するssh場合はローカルまたは経由で)。rs1

詳しくは以下をご覧ください。

関連情報