Linuxでcalを実行すると、今月の出力が反転し、現在の日付を強調するビデオが表示されます。その出力を hexdump -c に送ると、いくつかの興味深い結果が得られます。
0000000 N o v e m b e r 2 0 1 6
0000010 \n S u M o T u
0000020 W e T h F r S a \n
0000030 1 2 _ \b _ \b 3
0000040 4 5 \n 6 7
0000050 8 9 1 0 1 1 1 2 \n
0000060 1 3 1 4 1 5 1 6 1 7 1
0000070 8 1 9 \n 2 0 2 1 2 2
0000080 2 3 2 4 2 5 2 6 \n 2 7
0000090 2 8 2 9 3 0
00000a0 \n
00000b0 \n
00000bc
ご覧のとおり、今日強調表示されている「3」の前には見えないシーケンス_ \ b _ \ bが印刷されます。 _はアンダースコア(ASCII 16進数では5F)、\ bはCtrl-HまたはASCII 16進数では08です。これは何ですか?あいまいな端末コードがたくさんあることを知っていますが、 \e[7m のようなもっと標準的なコードを使いたいです。これ以上のことは、標準のprintfを使用して同じ文字を印刷できないことです。次のいずれかのコマンドのような関数です。 calの同じ動作を再現するには:
/usr/bin/printf "1 2 _\b _\b3 4 5\n"
/usr/bin/printf "1 2 _^H _^H3 4 5\n"
ここで ^H は Ctrl-V Ctrl-H を押して生成されます。ただし、どちらもcalと同じ逆ビデオ出力を生成できません。私はこのために小さなCプログラムを書いてみました。私もecho -eを使ってみました。興味深いことに、端末からビデオを反転させることはありませんが、less -Rを介して出力をパイプすると、色が黄色に変わり、下線が引かれます。他の端末では試してみましたが、ストレスを受けました。これはほとんど過度なように見えますが、_以外の文字を使用すると機能しないため、_ \ bが単一のコードシーケンスであると考えます。それでは、キャラクターの映像はどのように反転されますか?
これについての洞察力はありますか?
マニュアルページには、calの出力が元のUnix calコマンドとある程度互換性のあるバージョンでなければならないことが示されています。だから私はこれが古代のコードだと思います。
答え1
ほぼ少し多いようです。
まさに。議論80列コンソールに11個のタブがあるのはなぜですか?、Unix端子に関して機械式タイプライターの動作を考えるのが役立ちます。この場合、文字の前のシーケンス_
BS(バックスペース文字)は、その文字の下線を表す慣例です。一部の端末では、テキストに下線が引かれる方法だからです。別の制御シーケンスは、文字の後ろ_
のBSである。もちろん、初期端末では、何より重要なのかは重要ではありません。最新のビデオ端末では、最後の文字が「勝利」として記録され、古いデータが削除されます。したがって、_
BS <文字>順序が優先されます。
FreeBSD ncal
、つまりプログラムには、強調表示に関して2つの動作モードがあります。
so
出力が端末の場合は、termcapデータベースで現在の端末タイプの合計シーケンスを見つけ、強調表示されse
たテキストの両側にそのシーケンスをエクスポートします。 (実際にこれを実行するコードには、バッファがスタックの範囲外であり、その内容が後で使用されることに関連するバグがあり、誰もこれを見つけられなかったようです。)- 出力が端末でない場合は、
_
強調表示する各文字の前にBSシーケンスを含むテキストをエクスポートします。
_
(もちろん)あなたの端末がこのような内容を強調している端末の1つでない限り、端末にBSシーケンスを発行してそれを複製することはできません。これは端末エミュレータの場合ではなく、ここで使用するすべての端末や端末エミュレータの場合もほとんどわかりません。
ただし、次のことができます。フィルターul
この規則を使用するテキストは、この規則や他のタイプライターに似たいくつかの規則を認識し、それを端末の実際の制御シーケンスに変換し、termcapデータベースから検索するプログラムで使用されます。printf
コマンドの出力をフィルタリングすることもできますul
。
他の端末では試してみましたが、ストレスを受けました。
ncal
皮肉なことに、非ターミナルモード出力をプログラム的にフィルタリングすることは、実際には端末制御シーケンス自体を書くul
よりもncal
少し優れています。そしてncal
ターミナルを使って目立つモードでは、ul
実際の端末を使用しようとします強調するBSシーケンスを変換するときのモード(ある場合)_
。 termcapのマニュアルに記載されているように、ハイライトモードは端末に適した任意のモード(太字、反転ビデオ、または色を含む)であり、必ずしも下線を表示する必要はありません。端末の1つでは、明らかに下線と色の変更が組み合わされています。
また、ul
アンダースコアの開始/終了シーケンスはありませんが、アンダースコアの最後の文字シーケンスを持つ端末を処理できます。皮肉なことに、ul
端末がそれを買う余裕があれば本当に_
強調のためにすべての文字の後にBSを付けてncal
処理できないのです。
もちろん、エラーを処理するバッファul
はありません。ncal
☺
出力をにパイプすると、
less -R
色が黄色に変わり、下線が引かれます。
あなたが見つけたように、プログラムはBSシーケンスをless
理解し、プログラム的に処理します。まったく同じではありません。複数のBS文字を含むシーケンスは、同様の太字の文字シーケンスのように扱うことができます。できません。次の2つで見る内容を比較してみてください。_
ul
ul
_
less
/usr/bin/printf "1 2 ______\b\b\b\b\b\b\b 3 _\b4.\b\b\b45 6\n" |ur
/usr/bin/printf "1 2 ______\b\b\b\b\b\b\b 3 _\b4.\b\b\b45 6\n" |
良かった昔に帰る
残念ながら、今はまだ「良かった時代」です。最近では、この機能がほとんど使用されていないと人々が欺くことを避けてください。
マニュアルにはありませんが、ソースコードにはul
「それが出力であるため」Teletype Model 37の制御シーケンス処理を実装しようとしていることが示されていますnroff
。nroff
ターミナルが色、太字、イタリック体などの高度な機能を取得してから、長い間作成された元のUnixプログラムのGNU代替品を作成することができました。ECMA-48色、太字、イタリック体の制御順序です。実はそうです。通常の状況では。
nroff
端末に表示するためのマニュアルページ形式指定のためのGNU代替品です。悲しくも皮肉なことに、GNUツールが作成されてから約10年が経つにつれて、人々は1976年の「新しい」ECMA-48制御シーケンスの代わりに1968年の古いTeletype Model 37シーケンスを生成するようにGNUツールをブロックし始めました。この方法!)。デフォルトの動作を変更し、追加のditroff出力を強制する文書化されていないファイルを追加するオプションと一緒にman
呼び出されます。groff
端末からマニュアルページを読み取るたびに、手動システムが実行され、端末制御シーケンスに変換中または変換中の以前のgroff
Teletype Model 37制御シーケンスを使用して、手動ソーステキストを出力文字ストリームに忠実に変換します。less
more
追加読書
- ジョナサンデボインポラード(2016)。 nosh ユーザー空間仮想端末のマンページのイタリック体と色 (アーカイブバージョン、現在のバージョン)。スナックパック。
- ジョナサンデボインポラード(2017)。
拡張マニュアルページ
ul
(アーカイブバージョン、現在のバージョン)。提案。
答え2
Ctrl-H
バックスペースキーは、カーソルを左に1ステップ移動するキーです。以前は、アンダースコア、バックスペース、その他のいくつかの文字を送信することは、ハードコピー(「紙」)端末で何かに下線を引く方法でした。これは、出力で現在の日付を強調表示するために使用されますcal
。
私のプログラムはcal
実行時にkonsole
このシーケンスを出力しません。生成されたファイルを実行してscript -c cal
スキャンすると、calプログラムはエスケープシーケンスを使用して逆方向ビデオモードに切り替えるtypescript
ことを確認できます。<esc>[7m