回答:
これは、端末がキーボードから送信されたUpキーの生のキーコードを表す方法です。基本的に、シェルは通常キー押下をインターセプトしますが、ログインプロンプトでそれを行うことはありません。したがって、入力した文字は、他の文字(または数字など)とまったく同じようにコンソールに出力されます。
キーボードはイベントをコンピューターに送信します。イベントには、「スキャンコードnnnダウン」または「スキャンコードnnnアップ」と表示されます。チェーンのもう一方の端では、端末で実行されているアプリケーションは、文字シーケンスの形式で入力を期待します。(Xサーバーのように、生のアクセスを要求していない限り。)を押すAと、キーボードは「スキャンコード38ダウン」という情報を送信します。コンソールドライバーはキーマップを検索し、これを「キャラクター」に変換しますa
」に(修飾キーが押されていない場合)。
文字にならないキーまたはキーの組み合わせを押すと、情報は文字の観点からエンコードされる必要があります。いくつかのキーとキーの組み合わせには、対応する制御文字があります。たとえば、Ctrl+ Aは文字␁
(バイト値1)をReturn送信し、文字␍
(Ctrl + M、バイト値13)を送信します。␛
(エスケープ、バイト値27)文字で始まる文字のシーケンス。たとえば、キーUpはエスケープシーケンスに変換されます␛[A
(3文字:エスケープ、開き括弧、大文字のA)。
コンソールのユーザー名プロンプトは愚かであり、ほとんどのエスケープシーケンスを理解しません。慣れ親しんだラインエディションと履歴機能はありません。これらはシェルによって提供され、ログインするまでシェルはありません。そのため、エスケープシーケンスが表示されるだけです。␛
文字にはグリフがないため、として表示され^[
ます。^
記号は、伝統的に制御文字の接頭辞として使用され、脱出がある^[
ので、そのバイト値の:それはバイトの値だ[
、マイナス64。
Upシェルプロンプトでを押すと、同じ3文字のシーケンスがシェルに送信されます。シェルはこれをコマンドシーケンスとして解釈します(通常、前の履歴項目を呼び出すため)。押すとCtrl+ Vその後、Upシェルプロンプトで、このインサートは、プロンプトでエスケープシーケンス:Ctrl+は、V文字通り、代わりにコマンドとしてそれを解釈するの次の文字を挿入するためのコマンドであるので、␛
文字はエスケープシーケンスの開始と解釈されていません。
一部のキーは修飾子のみであり、ターミナルアプリケーションに送信されません。たとえば、を押すとShift、この情報はターミナルドライバーに残り、その後を押すAと考慮されるため、ドライバーA
はの代わりにアプリケーションに送信されますa
。
さらに、一部のファンクションキーがコンソールにマップされない場合があります。
GUIでの同様のビューについては、bashのメタキーとはをご覧ください。
キーが「ターミナル」(つまり、ターミナルエミュレータアプリケーション)によってどのように表されるかではありません。表示されているのは、1行上に移動するための ANSIコード(ANSIエスケープシーケンス)ですが、印刷可能な形式に変換されています。
キーボードハードウェアは「スキャンコード」を送信しますが、それらは翻訳され、コマンドラインレベルのアプリケーションに文字として表示されます。キーAは1バイトになりA
ます。Shiftキーが押されている場合(またはShift Lock)、a
それ以外の場合。
ANSI準拠の端末では、矢印キーは1文字(ASCII文字セットには矢印のコードはありません)ではなく、3文字の「エスケープシーケンス」を送信しますescape-[-A
。他の3つの矢印キーはescape-[-B, C, D
です。
同じ文字シーケンスは、古い物理ANSI端末に送信(エコー)されると、カーソルを1行上に移動します。ターミナルエミュレータを含む多くのプログラムは、これらの文字シーケンスを認識して適切な処理を行います。ターミナルエミュレータはカーソルを上に移動します(これによりcurses
ライブラリがカーソルを移動します)が、bash
代わりにそれをインターセプトして履歴をスクロールします。
画面上でカーソルを移動するのに使用できないプログラムでカーソルがいたるところに収まるのを避けるために、キーボード入力にESCが印刷可能なシーケンスとして表示されることがよくあります^[
(エスケープがに対応するためcontrol-[
)。これは、実際には端末デバイスインターフェイスによって処理されます。を参照してくださいstty(1)
。その結果、上矢印はとして表示され^[[A
ます。を入力しcat
、リターンキーを押して矢印キーを押すと、コマンドラインからこれが表示されます。これは、コンソールのログイン画面で見たものでもあります。
最後に:Control、Alt、あなたが言及した他のキーは、文字列にマップされません。これらは、別のキー押下によって送信される文字に影響を与えます(上記のa
/ A
例のように)か、単にテキストへのマッピングがありません。このようなキー押下は、キーボードイベントをリッスンするプログラムによってのみ検出できます。それらは、標準入力から読み取ることで見ることはできません(またはファイルに書き込むこともできません)。
この動作はシェルごとに異なります。ほとんどのシェルreadline
は、プロンプト内の行を編集するために呼び出されるライブラリを使用します。このライブラリの完全なコマンドリファレンスを次に示します。そのため、アプリケーションが使用しているときに、readline
このコマンドを使用して行を編集およびナビゲートできます。
コマンド履歴をナビゲートするために、垂直矢印キーがreadlineで構成されます。また、ログインプロンプトにはコマンド履歴がありません。そのため、文字^[[A
と^[[B
は画面に印刷されます。どういう^[[A
意味ですか?
bashのマニュアルページには、PROMPTING
次のように記載されています。
\[ begin a sequence of non-printing characters, which could be used to embed
a terminal control sequence into the prompt
ANSIの矢印キーのエスケープシーケンスは次のとおりです。
[ValueA
カーソルを上に(Value
空にすることができます)
[ValueB
カーソルを下に移動(Value
空になる場合があります)
login
、これはには関係ありませんbash
。
bash
またlogin
、同じライブラリ(readline)を使用して行を編集しています。違いはlogin
、垂直矢印キーをコマンドのように解釈しないことですbash
。
^[
表現のように見えることを意図しescape
ていますが、それらは異なるものです。Bashはどんな構文でも使用できたはずです。あなたが書くこと、に\[A
:、3つの文字の出力はbash ^[
、(すなわちエスケープ)[
、A
。
これらはANSIエスケープコードです。^[
シェルがESC
バイト(ASCIIバイト27)を表示するために使用する表記法です。あなたの例は、テキストが続くESCバイトです[A
。Wikipediaの記事で見ることができるように、^[[
(にESC
続いて[
)はControl Sequence IntroducerまたはCSIです。CSI A
カーソルを1列上に移動することを意味します。
端末にエスケープコードを表示する場合は、CTRL + Vを入力してから、別のキーシーケンスを入力します。たとえば、CTRL + Vの後に上矢印が続くと、が表示されます^[[A
。
getty
またはlogin
に飲み込まれますが、理由はわかりません。経験に基づいた推測では、印刷画面は歴史的な理由でカーネルによって特別に解釈されます。ただし、修飾子以外は、100%確信はありません。