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

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

バックスペース()文字の動作に関する内容です\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

おすすめ記事