80列のコンソールに11個のタブストップがあるのはなぜですか?


2

各タブはデフォルトで8カラム進むため、80カラムのコンソールには正確に10のタブストップがあると想定します。これは反証することができます:

$ printf "1\t2\t3\t4\t5\t6\t7\t8\t9\t0\ta"

出力は2行になると予想されます。これは、10個のタブストップがあり、80列すべてのスペースと、次の行にプッシュされる単一の文字があるためです。ただし、このコマンドは、xterm、gnome-terminal、およびrxvtに単一の出力行を生成します。

起こったことは、最後のタブストップが魔法のように1文字少ないスペースを取ることです。

一方、expand(1)はタブのスペースが8であることを維持するため、

$ printf "1\t2\t3\t4\t5\t6\t7\t8\t9\t0\ta" | expand

80カラムのコンソールで魔法のように2行を生成します。

何らかの標準のようです。しかし、グーグルでソースを見つけることができません。

Linuxでのみテストされていますが、これはすべてのUNIXで共有されていると思います。


それらはどれもコンソールではありません。これらはすべてGUI端末エミュレーターです。
JdeBP 14

回答:


14

80列のコンソールには、タブストップが9つしかありません。

最初にコメントを拡大しましょう。あなたは、実際にテストしていない任意のコンソールを。これらはすべてGUI 端末エミュレータプログラムです。幸いなことに、実際のコンソール(少なくともLinuxとFreeBSD上)でもこの動作が見られます。

しかし、それはあなたが主張する行動ではありません。11個のタブストップは示されていません。9を示します。

タブストップを適切に理解するには、「常にN個のスペースに展開する」を捨てる必要があります。アイデア。タブストップを備えた機械式タイプライターを使用できる場合は、その仕組みを確認してください(タブがキャリッジの突き出たピンによって設定される)。UnixおよびLinuxの世界では、端末のタブストップはこのように機能します。

(端末に到達する前に、出力ストリームのタブ文字をスペース文字に置き換えて、ソフトタブを有効にするように回線制御を設定できます。ここでは、回線制御ではなく端末自体によって実行されるハードタブについて説明ます。。ハードタブでTABは、ボーンフィードキャラクターが端末に送信されます。逆に、ソフトタブでは、最初に説明した動作が発生しません。設定stty tab3してみてください。

初期化されたように、端末にはタブストップまったく設定されていません。早い段階でgetty、またはresetコマンドまたはそれに類するもの(システムによって異なる)は、特定の列にタブストップ設定する一連のスペース文字とエスケープシーケンスを出力します。列とエスケープシーケンスでさえも配線されている場合があります。ただし、ほとんどの場合、コマンドはtermcap / terminfoデータベースの情報を検索します。すべてのタブをクリアするためのエスケープシーケンスを提供するterminfo機能はtbc;です。このhts機能は、現在の列にタブを設定するためのエスケープシーケンスを提供します。この it機能は、デフォルトでタブストップ間の列数を指定します。termcapのために、同等の機能でありitctおよびst

このコマンドは端末サイズを取得し(カーネル、システムコール、またはterminfo / termcapレコードの別の部分から)、列数を調べ、itスペースとそれに続くできるだけst多くの列のシーケンスを繰り返し出力します。、最後にキャリッジリターンを出力して列#0に戻ります。これはまさに 1は、多くの機械式タイプライターでタブストップのセットを設定方法:スペースを繰り返し、次のタブストップに、ヒット、ピンを押し出し右マージンまで繰り返し、左に戻ってキャリッジをプッシュするレバーを「タブストップ設定」 。

it通常は8として与えられる80列幅の端末では、コマンドはこれを9回行い、8、16、24、32、40、48、56、64、および72列にタブストップを設定します。

列0にはタブストップ(プログラムのバグを除く)はありません。これが最初のカウントミスです。また、列80にタブストップはありません。これは2回目のカウントミスです。「なぜ」、「それですか?」できないため、まず、それがあることタブストップを設定する欄80に。カーソルは、80列の端末で列0から列79に移動します。

第二に、TABキャラクターの行動について考えなければなりません。一般的な考えに反して、次の8列の倍数に移動するのに十分なスペースに拡張されませ。UnixおよびLinux端末は、機械的なタイプライターのように機能します、覚えておいてください。メカニカルタイプライターの世界では、タブキーはキャリッジをタブストップピンまたは右マージンで停止するまで移動します。(いくつかの巧妙な詰まりは、この時点でマージンリリースに言及するかもしれません。これは、明白な理由のために、UnixおよびLinux端末にはない機械式タイプライターにはあるものです。)

TABUnixおよびLinux端末の文字は、実際にはまったく同じように機能します。それに応じて、端末は次の設定されたタブストップまたは右端の列に到達するまでスペースを出力します。それがここで起こっていることです。カーソルが79列目にあるとき、TAB好きなだけ文字を書くことができ、何も起こりません。右端の列を超えるタブ移動はありません。

termcap / terminfoシステムでは、設定可能なハードタブをオプションにすることができます。しかし、すべてでテストしたプログラムは、「xterm」タイプのターミナルエミュレータを提供します。(理解できるエスケープシーケンスxtermは、termcap / terminfoデータベースのエントリ/エントリで指定されたものです。)また、最近では、FreeBSD仮想コンソールのターミナルエミュレータも同様です。Linux仮想コンソールのターミナルエミュレーターは、実際にはわずかに異なるターミナルタイプで、と指定されていlinuxます。(これはFreeBSD仮想コンソールにも当てはまりました。cons25タイプ。FreeBSDは、仮想コンソールでUTF-8サポートを取得するプロジェクトの一環として、カーネルターミナルエミュレーターをバージョン9.0でxterm互換に変更しました。タブ機構。

(ソースを読んで楽しむ人のために:を見てTabNext()TabToNextStop()の関数tabs.cxtermソースコード。)

自分で試してみることができます。次のコマンドを実行します。

tbc=$(tput tbc) hts=$(tput hts)
printf '%s\r%s\r\n' "${tbc}" "a${hts}aaa${hts}aaaaaaa${hts}aaaaaaaaaaaaa${hts}aaaaaaaaaaaaaaaaaa${hts}"

その後、コマンドを再度実行します。正確に5つのタブストップが設定されています。${hts}コマンドでを数えるか、a文字の行を見てください。5番目を超えて、このTAB文字は、その比phor的なタイプライターの馬車に、残りのすべてを右マージンまでむしゃむしゃさせます。

次の(印刷する、非TAB)文字は、左マージンへの自動キャリッジリターン、および次の行への改行を引き起こします。termcap / terminfoの用語では、xterm端末タイプには自動マージンがあります。理論的には、UnixとLinuxは自動マージンのない端末で動作します。あなたのprintfコマンドは、キャリッジリターンを書いたまで、どのくらいのより多くのあなたの出力は関係ない、コラム79で動けなくなるでしょう。実際には、このようなデバイスは、今日のほとんどの人の心を揺さぶるでしょう。


ありがとうございました!設定可能なTABは、コンソールでスプレッドシートソフトウェアを作成する機能を提供しているように思えます。しかし、成熟したものは見つかりませんでした-私は数年前にそのようなオープンソースツールを使用しましたが、名前は忘れられていました。
タンクマン

ちなみに、このタブストップケースをテストするためにほこりを払わなかったものの、実際には、中国語フォントとZ-80 CPUが埋め込まれた実際のコンソールを1997年から持っています。
タンクマン

その答えは、ハッカーの辞書の付録にあるはずです。弾力性のあるタブストップvimのタブの秘密を研究しているときに、どういうわけかここにたどり着きました。100%の価値があります。私は、オリンピアのタイプライターの確実に持ち上げられた右上のTABキーに実際の物理的エネルギーを入力しなければならないという気持ちを覚えています。
デビッドトンホーファー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.