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 hexでは5F)であり、\ bはCtrl-Hまたは08in ASCII hexです。これは何ですか?あいまいな端末コードがたくさんあることは知っていますが、期待しています\ 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-VCtrl-Hを押して作成します。しかし、これらはどちらも、calと同じ逆ビデオ出力を生成しません。私もそれをするために小さなCプログラムを書いてみました。 echo-eも試してみました。興味深いのは、ターミナルでビデオを反転させない一方で、より少ない-Rから出力をパイプすると、色が黄色に変わり、下線が引かれることです。他の端末では、下線を引いてみました。重ね打ちのように見えますが、_以外の文字を使用すると機能しないため、_\bは単一のコードシーケンスであると思われます。そして、そのキャラクターのビデオはどのように反転されますか?
これについて何か洞察はありますか?
マニュアルページには、calの出力は、元のUnixcalコマンドとビット互換バージョンのビットであると想定されていると書かれています。だから私はこれがいくつかの古代のコードであると推測することしかできません。
Ctrl-H
はバックスペースで、カーソルを1ステップ左に移動します。古き良き時代に、アンダースコア、バックスペース、およびその他の文字を送信することは、ハードコピー(「紙」)端末で何かに下線を引く方法でした。これは、cal
の出力で当日を強調するために使用されました。
私のcal
プログラムは、konsole
で実行すると、このシーケンスを出力しません。 script -c cal
を実行して結果のTypeScript
ファイルを調べると、calプログラムがエスケープシーケンス<esc>[7m
を使用して逆モードビデオに切り替えていることがわかります。
重ね打ちのようです
それがまさにそれです。 https://superuser.com/a/711019/38062 のように、Unix端末に関しては機械式タイプライターの動作を考えると役立ちます。この場合、文字の前のシーケンス_
BS(バックスペース文字)は、その文字の下線を示すために使用される規則です。一部の端末では、テキストに下線を引く方法があるためです。代替の制御シーケンスは、文字の後のBS _
です。もちろん、元の端末では、何が何を超えたかは問題ではありませんでした。
このプログラムが何であるかであるFreeBSDncal
には、強調表示に関して2つの操作モードがあります。
so
およびse
シーケンスを検索し、強調表示されたテキストのいずれかの側に出力します。 (実際には、これを行うコードにバグがあり、スタック上のバッファがスコープ外になり、その内容が後で使用されるため、誰も発見していないようです。)_
BSシーケンスが付いたテキストを出力します。_
BSシーケンスを端末に発行してこれを複製することはできません。ただし、(もちろん)端末が端末の1つであり、これが下線を引く方法である場合を除きます。これはターミナルエミュレーターには当てはまりません。また、ここで使用しているターミナルやターミナルエミュレーターにも当てはまります。
ただし、filterこの規則を使用するテキストは、ul
プログラムを介して、これと他のいくつかのタイプライターのような規則を認識し、端末の制御シーケンスが実際にあるものに変換して、で検索することができます。 termcapデータベース。 printf
コマンドの出力をul
でフィルタリングすることもできます。
他の端末では、下線を引いてみました。
皮肉なことに、ncal
プログラムを介してul
の非端末モード出力をフィルタリングすることは、実際にはncal
に端末制御シーケンス自体を書き込ませるよりもわずかに優れています。 ncal
は端末のstandoutモードを使用しますが、ul
は、_
BSシーケンスを変換するときに、端末の実際のnderlineモード(ある場合)を使用しようとします。 termcapのマニュアルで説明されているように、目立つモードは端末に適したもの(太字、反転ビデオ、色など)であり、必ずしも下線が引かれているわけではありません。端子の1つでは、明らかに下線と色の変更の組み合わせです。
さらに、ul
は、開始/終了シーケンスに下線が付いていないが、最後の文字シーケンスに下線が付いている端末にも対応します。皮肉なことに、ul
は端末が本当に各文字の後にBS_
を付けることで下線を引く場合に対応しますが、ncal
は対応しません。
そしてもちろん、ul
にはncal
のバッファ処理のバグはありません。 ☺
出力を
less -R
にパイプすると、色が黄色に変わり、下線が引かれます。
お気づきのとおり、less
プログラムは_
BSシーケンスを理解し、ul
プログラムと同じように処理します。それは完全に同じではありません。 ul
は、複数の_
およびBS文字を含むシーケンスを処理でき、太字の同様のシーケンスも処理できます。 less
はできません。これら2つからわかるものを比較してください。
/ usr/bin/printf "1 2 ______\b\b\b\b\b\b 3 _\b4。\ b\b\b45 6\n" | ul
/ usr/bin/printf "1 2 ______\b\b\b\b\b\b 3 _\b4。\ b\b\b45 6\n" | less
古き良き時代に戻って
悲しいことに、これらはまだ「古き良き時代」です。これが今日ではめったに使用されないと人々に信じ込ませないでください。
マニュアルにはありませんが、ul
のソースコードは、「それがnroff
の出力である」ため、テレタイプモデル37の制御シーケンス処理を実装しようとしていることを示しています。 GNU元のUnixnroff
プログラムの代わりに、端末が色、太字、斜体などの高度な機能を取得してからずっと後に作成され、色、太字、および斜体のECMA-48制御シーケンスを生成できます。イタリック。実際にはそうします通常の場合。
nroff
とそのGNU置換は、端末に表示するためのマニュアルページのフォーマットに使用されます。悲しいことに、皮肉なことに、それが書かれてから約10年後に、人々はGNUツールにより、1976年の「新しい」ECMA-48制御シーケンスの代わりに1968年の古いテレタイプモデル37シーケンスが生成されました(原文のまま)。デフォルトの動作を変更するオプションを使用して、man
にgroff
を呼び出させました。そして、余分なditroff出力を強制する文書化されていないファイルを追加しました。
端末で手動ページを読むたびに、手動システムはgroff
を実行しています。これは、手動のソーステキストをこれらの古いTeletype Model 37制御シーケンスを使用して出力文字ストリームに忠実に変換し、less
またはmore
は端末の制御に変換します。シーケンス。
ul
の改良されたマニュアルページ。提案。