コンソールログインにいるときはいつでも、 up 以前に入力したコマンドを表示するために、意図的に矢印を付けます。しかし、私はこれを見ます^[[A
。
しかし、私が押すと CtrlAltPrint ScreenScroll LockPause BreakPage UpPage DownWin キーは文字をエコーしません。
背後にある理由は何でしょうか?
します^[[A
文字の種類は何かを意味しますか?
キーボードはコンピューターにイベントを送信します。イベントは、「scan code nnn down」または「scan code nnn up」と言います。チェーンの反対側では、端末で実行されているアプリケーションは、文字のシーケンスの形式での入力を想定しています。 (Xサーバーのようにrawアクセスを要求していない限り)。 A、キーボードは「スキャンコード38ダウン」という情報を送信します。コンソールドライバーは keymap を検索し、これを「文字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のメタキーとは何ですか? を参照してください。
これは、キーボードが端末に送信したUpキーの生のキーコードを端末が表す方法です。基本的に、シェルは通常キープレスをインターセプトしますが、ログインプロンプトでそれを行うことは何もありません。入力した文字は、他の文字(または数字など)と同じようにコンソールに出力されます。
キーが「ターミナル」(つまり、ターミナルエミュレーターアプリケーション)によってどのように表されるかについてではありません。表示されているのは、1行上に移動するためのANSIコード( ANSIエスケープシーケンス )ですが、印刷可能な形式に変換されています。
キーボードハードウェアは「スキャンコード」を送信しますが、それらは変換され、コマンドラインレベルのアプリケーションに文字として表示されます。キー A 1バイトになります。Shiftキーが押されている場合(またはShift Lockが押されている場合)A
、それ以外の場合はa
。
ANSI準拠の端末では、矢印キーは1文字を送信しません(ASCII文字セット)に矢印のコードはありません)が、3文字の「エスケープシーケンス」: escape-[-A
。他の3つの矢印キーはescape-[-B, C, D
です。
同じ物理シーケンスが古い物理ANSI端末に送信(エコー)された場合、カーソルは1行上に移動します。ターミナルエミュレータを含む多くのプログラムは、これらの文字シーケンスを認識し、適切な処理を行います。ターミナルエミュレータはカーソルを上に移動します(これによりcurses
ライブラリがカーソルを移動します)が、bash
はインターセプトします代わりに履歴をスクロールします。
画面内でカーソルを移動する必要のないプログラム内のすべての場所でカーソルが終了することを回避するために、キーボード入力でESCが印刷可能なシーケンス^[
として表示されることがよくあります(エスケープはcontrol-[
に対応するため)。これは実際には端末デバイスのインターフェースによって処理されます。 stty(1)
を参照してください。その結果、上矢印は^[[A
として表示されます。 cat
と入力してReturnキーを押し、矢印キーを押すと、コマンドラインからこれが表示されます。これは、コンソールのログイン画面にも表示されたものです。
最後に: 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
は空にすることができます)
TLDR
上矢印キーを押したときに生成される生のキーコードを出力するsh
を実行している可能性があります。
bash
のようなより高度なシェルは、これらのキーコードをインターセプトして、何かを行います。例えば。履歴の最後のコマンドを表示します。
それらは ANSIエスケープコード です。 ^[
は、シェルがESC
バイト(ASCIIバイト27)を表示するために使用する表記です。したがって、例はESCバイトの後にテキスト[A
が続きます。ウィキペディアの記事を見るとわかるように、^[[
(ESC
の後に[
)はControl Sequence IntroducerまたはCSI。 CSI A
は、カーソルを1列上に移動することを意味します。
端末でエスケープコードを表示するには、CTRL + Vを押してから、別のキーシーケンスを入力します。たとえば、CTRL + Vに続いて上矢印を押すと、^[[A
が表示されます。
コマンドシェル、たとえばBashは、上向きの矢印をアクション「前のコマンドを取得する」に変換するプログラムです。コマンドシェルを実行していません。