を押すCtrl+Xと、端末エミュレーターはバイト0x18を擬似端末ペアのマスター側に書き込みます。
次に何が起こるかは、tty回線制御(マスター側(エミュレーターの制御下)とスレーブ側(端末で実行中のアプリケーションが対話する)の間にあるカーネル内のソフトウェアモジュール)の構成方法によって異なります。
そのtty回線制御を設定するstty
コマンドがコマンドです。
そのようなダムアプリケーションを実行しているとき、cat
そのstdinがターミナルであるかどうかを意識せず、気にしません、ターミナルはデフォルトの標準モードにあり、ttyライン制御は粗いラインエディターを実装します。
粗いラインエディタ以上のものを必要とする一部のインタラクティブアプリケーションは、通常、起動時にこれらの設定を変更し、終了時に復元します。現代のシェルは、そのプロンプトでそのようなアプリケーションの例です。独自のより高度なラインエディタを実装します。
通常、コマンドラインを入力している間、シェルはttyラインディシプリンをそのモードにし、Enterキーを押して現在のコマンドを実行すると、シェルは通常のttyモードを復元します(プロンプトを発行する前に有効でした)。
このstty -a
コマンドを実行すると、ダムアプリケーションで使用されている現在の設定が表示されます。あなたは見てそうだicanon
、echo
とechoctl
設定が有効にされています。
それが意味することは:
icanon
:その粗雑なラインエディタは有効になっています。
echo
:入力した文字(ターミナルエミュレーターがマスター側に書き込む文字)はエコーバックされます(ターミナルエミュレーターが読み取れるようにします)。
echoctl
:そのままエコーされる代わりに、制御文字はとしてエコーされ^X
ます。
だから、あなたがタイプしA B Backspace-aka-Ctrl+H/? C Ctrl+X Backspace Returnたとしましょう。
端末エミュレータは次を送信しますAB\bC\x18\b\r
。回線制御はエコーバックします:AB\b \bC^X\b \b\b \b\r\n
、スレーブ側から入力を読み取るアプリケーション(/dev/pts/x
)が読み取りますAC\n
。
アプリケーションが見るのはAC\n
のみであり、あなたのプレスがEnterそうである場合にのみ、^X
そこでの出力を制御することができません。
echoの場合、最初の^H
(^?
一部の端末ではerase
設定を参照)が\b \b
端末に送り返されることに気付くでしょう。これは、カーソルを戻す、スペースで上書きする、カーソルを再び戻すシーケンスであり、2番目の^H
結果は\b \b\b \b
これら2つの文字^
とX
文字を消去します。
^X
(0x18の)自体に変換されていた^
とX
出力用。のようにB
、Backspaceで削除したため、アプリケーションに到達しませんでした。
\r
(別名^M
)は、エコー用に()、アプリケーション用に\r\n
()に変換されました。^M^J
\n
^J
したがって、これらの愚かなアプリケーションのオプションは何ですか?
- 無効
echo
(stty -echo
)。これにより、制御文字のエコー方法が効果的に変わります。何もエコーしません。実際には解決策ではありません。
- 無効にし
echoctl
ます。これにより、制御文字(^H
、^M
...、およびラインエディタで使用される他のすべて)がエコーされる方法が変更されます。これらはそのままエコーされます。それは、例えば、ESC文字は次のように送信されている\e
(^[
/ 0x1b
(端末によるエスケープシーケンスの開始として認識されている)、)バイト^G
あなたが送って\a
(あなたの端末のビープ音を作り、BEL)...未オプション。
- 粗いラインエディターを無効にし
stty -icanon
ます()。粗雑なアプリケーションはずっと使いにくくなるため、実際にはオプションではありません。
- カーネルコードを編集してttyライン制御の動作を変更し、制御文字のエコーが送信される
\e[7m^X\e[m
だけではなく^X
(\e[7m
通常、ほとんどの端末でリバースビデオが有効になります)。
オプションrlwrap
は、そのようなラッパーを使用して、愚かなアプリケーションに派手なラインエディターを追加するためのダーティハックです。そのラッパーは、事実上read()
、端末デバイスからreadline行エディター(tty行規則のモードを変更する)への呼び出しに単純なs を置き換えようとします。
さらに進むと、ターミナルからのすべての入力を乗っ取って、GNUスクリーンの機能に依存するzshのラインエディター(リバースビデオでs を強調表示する)を通過するこのようなソリューションを試すこともできます。^X
:exec
独自のラインエディタを実装するアプリケーションの場合、エコーの実行方法を決定するのはアプリケーション次第です。bash
制御文字のエコー方法のカスタマイズをサポートしていないreadlineを使用します。
についてはzsh
、以下を参照してください。
info --index-search='highlighting, special characters' zsh
zsh
デフォルトでは印刷できない文字を強調表示します。たとえば、強調表示をカスタマイズできます。
zle_highlight=(special:fg=white,bg=red)
これらの特殊文字の赤の強調表示に白の場合。
ただし、これらの文字のテキスト表現はカスタマイズできません。
UTF-8ロケールで、0x18のは次のようにレンダリングされる^X
、\u378
、\U7fffffff
として(二未割り当てのUnicodeコードポイント)を<0378>
、<7FFFFFFF>
、\u200b
として(不実際に印刷可能なUnicode文字)<200B>
。
\x80
iso8859-1ロケールでは^�
...などとしてレンダリングされます。
bash
それはreadline
そのようなものを処理するためであり、他のほとんどの場合はttyドライバーです。