端末のバックスペースキーの動作

端末のバックスペースキーの動作

バックスペース()文字の動作に関する内容です\b。次のCプログラムがあります。

int main() {
    printf("Hello\b\b");
    sleep(5);
    printf("h\n");
    return 0;
}

私の端末の出力は次のとおりです。

Helho

カーソルが次の行の最初の位置に移動します。

まず、内容全体は5秒の休止後にのみ印刷されるため、カーネルからターミナルへの出力がラインバッファリングされていると推定されます。今私の質問は次のとおりです。

  1. 2つのスペースの後ろに移動して(2番目の)位置に達したので、\b\b交換と同様の方法で交換する必要がありますl。なぜできないの?lho\n
  2. 行を削除すると、削除せずに2文字をprintf("h\n");印刷して返します。Hello私はこれが非破壊的なバックスペースキーのためであることを他の答えから得ました。入力と出力が異なる動作をするのはなぜですか?つまり、端末に何かを入力して(同じプログラムでも)バックスペースを押すと、最後の文字は削除されますが、出力は削除されません。なぜ?

役に立つ場合は、Ubuntuシステムのxterm端末でbashを使用しています。

答え1

まず、内容全体は5秒の休止後にのみ印刷されるため、カーネルからターミナルへの出力がラインバッファリングされていると推定されます。

いいえ、あなたの結果プログラムカーネルのラインバッファリングがあります。これは端末のstdio場合のデフォルト動作です。出力バッファリングをオフにするstdout呼び出しが追加されました。バラよりsetbuf(stdout, NULL)stdoutsetbuf(3)

  1. その時の位置に2つのマスの後ろに移動したので、\b\b交換する方法と似ているのでl交換する必要があります。なぜできないの?lho\n

改行文字は単にカーソルを移動して画面をスクロールするため、端末の文字の外観位置を占めるように見える文字で印刷されません。これが文字の形を置き換えると仮定すると、どのような外観でしょうか?

  1. 同じプログラムで何かを入力してバックスペースを押すと、最後の文字は削除されますが、出力は削除されません。なぜ?

さて、入力したときに何が起こるかは、端末がどのモードにあるかによって異なります。おおまかに言えば、端末自体がデフォルトの行編集(バックスペースが処理されている)を提供する一般的な「料理」モード、またはすべてのキーストロークがアプリケーションに入り、アプリケーションがどのように処理するかを決定する「生」モードです。あります。それらとそれに応答して出力される内容。 Cooked モードは通常「local echo」で使用されます。ここで、端末(ユーザーにローカル)は文字が入力されると印刷されます。生モードでは、アプリケーションは通常、入力された文字をエコーし​​て表示される内容を完全に制御します。

端末モードの説明については、次の質問を参照してください。 「生」デバイスドライバと「調理済み」デバイスドライバの違いは何ですか?

たとえば、を実行すると、catターミナルはベーキングモード(デフォルト)になり、ライン編集を処理します。たとえば、クリックすると空の入力のみがxBackspaceCtrl-D読み取られ、cat入力が終了したことを示します。を使用してこれを確認できますstrace。ただし、インタラクティブな Bash シェルを実行すると、バックスペースキーを独自に処理し、ユーザーが期待する文字を消去するのに適していると判断される内容を出力します。


strace -etrace=read,write -obash.trace bash上記のシーケンスを入力した後、出力の一部は次のとおりですxBackspaceCtrl-D

read(0, "x", 1)                         = 1
write(2, "x", 1)                        = 1
read(0, "\177", 1)                      = 1
write(2, "\10\33[K", 4)                 = 4
read(0, "\4", 1)                        = 1

まず、Bashを実行しreadて端末にwrite出力します。次に、バックスペース文字(8進文字コード0177または10進文字コード127)を読み取り、カーソルを後ろに移動してxバックスペース文字(8進数010、10進数8 (*))を出力します。そして出力制御シーケンス行末を消去するために使用されます<ESC>[K。最後は、Bashがプログラムを終了するために使用されます\4Ctrl-D

(*入力にはCtrl-H10進文字コード8があります。バックスペースは、端末の設定方法に応じて、ここまたは127と同じです。)

対照的に、同じ実験では、cat「ファイルの終わり」条件であるゼロバイトの単一の読み取りのみが表示されます。ファイルの終わりは、接続されたパイプまたはソケットが閉じられたか、実際のファイルの終わりであるか、またはベークモードでCtrl-D端末から受信されたことを意味できます。

read(0, "", 131072)                     = 0

特に、バックスペースまたはの実際のコードは表示されず、cat端末で処理されます。これは、カーネルの仮想ターミナルドライバ、シリアル接続などを介した物理的な物理ターミナル、または同じシステムまたはSSH接続のリモート側で実行されるxtermなどのターミナルエミュレータです。ユーザー空間ソフトウェアには重要ではありません。xCtrl-D

答え2

コード(\bなど\n)はテキストではなくカーソルを移動します。

テレタイプ、ゴルフボールプリンタなどで、太字やキャンセルなどの驚くべき効果を得るために、プリンタでカーソルを操作しなければならなかった「良い昔」から、この動作が起きたことがわかります。

\b挿入ポイントを後ろに移動すると上書きが可能になります。デジタル画面では以前の内容は消去されますが、古いプリンタでは上書きされた文字が表示されます。

\nカーソルを新しい行に移動しますが、前の行のテキストは後ろに置きます。これは、カーソルを行の先頭に戻し、プリンタに1行上にスクロールするように指示するCRLFです。

これCR、LF、CRLFコードこれらの新しい効果を達成するために古い機器を操作する必要性にも関連しています。

.....そして印刷されたページから文字を削除する方法はありません。印刷用に公開する直前に文字を削除する必要があります。

編集する

2番の項目に答えてください。入力と出力はユーザーが指示するため、さまざまなタスクを実行します。

\b削除ではなく、INSERTを閉じる左矢印と同じです。

\nEnterキーではなく、下向き矢印(LF)とHOME(CR)と同じです。

答え3

まず、これらのことについて知りたい場合は、以下を読んでください。

頼む、

...何かを入力してバックスペースを押すと、最後の文字は削除されますが、出力は削除されません。なぜ?

以下はあなたのためのいくつかの常識です。 Unixの初期(Linuxが存在する前の1970年代)には、バックスペースキー1 いいえ入力した文字を削除すると、ユーザーは嫌いです。と入力してbeastバックスペースを3回押すと、まだ悪魔の目がbe|astあなたを見つめています(|カーソルを表します)。入力した後もst(常に欲しいのでbest)画面が表示され続け、best|t混乱します。

BackspaceSpaceBackspace 多くのユーザーは、文字を空白に置き換え/破壊するために(手動で)入力習慣を開発しています。 削除それらを。結局のところ(1979年または1980年代初め)、開発者たちは心を和らげ、それを自動的に作りました。

バックスペースを押すと、カーネルの tty 行ルールは (単純な場合) Ctrl-H、空白、および別の Ctrl-H を印刷して前の文字を消去します。
源泉:テキスト入力中にバックスペースを押すとUnixからコンテンツを削除する方法

ここで、「Ctrl-H」はバックスペースキーの制御コードです。

場合によっては、このオプションをオフにしてstty -echoeechoe = "echo"と-「こんなことはしない」という意味)。
____
1実際、最初はバックスペースキーはバックスペースではなかったが、それは別の話です。

関連情報