私は最近シェルで多くの時間を費やしており、タブのオートコンプリートがどのように機能するのか疑問に思っています。その背後にあるメカニズムは何ですか? bashはどのようにしてすべてのディレクトリの内容を知るのですか?
オートコンプリートには2つの部分があります。
Readjeライブラリは、fixjeで既に述べたように、コマンドラインの編集を管理し、タブが押されたときにbashを呼び出して補完を有効にします。次に、Bashは補完候補のリストを提供し(次のポイントを参照)、readlineは既に入力された文字によって明確に識別される文字を挿入します(readlineライブラリをかなり構成できます。セクション コマンドライン編集 詳細については、Bashマニュアルの)
Bash自体には、個々のコマンドの完了メカニズムを定義するcomplete
が組み込まれています。現在のコマンドに対して何も定義されていない場合、ファイル名による補完を使用しました(Ignacioが述べたように、opendir/readdirを使用)。
独自の補完を定義する部分は、セクション Programmable Completion で説明されています。つまり、complete «options» «command»
を使用して、コマンドの完了を定義します。たとえば、complete -u su
と言うsu
コマンドの引数を完了するとき、現在のシステムのユーザーを検索します。
これが通常のオプションがカバーできるよりも複雑な場合(たとえば、引数インデックスまたは以前の引数に応じて異なる補完)、-F function
を使用して、シェル関数を呼び出して可能な補完のリストを生成できます。 。 (これは、サブコマンドや場合によっては指定されたオプションによっては非常に複雑なgit補完などに使用され、時にはブランチの名前(bashが何も知らない)を使用します)。
単にcomplete
を使用して、現在のbash環境で定義されている既存の補完を一覧表示して、可能なことについて印象を与えることができます。 bash-completionパッケージがインストールされている場合(または、システムで名前が付けられている場合)、多くのコマンドの補完がインストールされます。Wrikkenが述べたように、/etc/bash_completion
にはbashスクリプトが含まれ、これを設定するためのスタートアップ。追加のカスタム完了スクリプトを/etc/bash_completion.d
に配置できます。これらはすべて/etc/bash_completion
から供給されます。
基本に興味がある場合:Bashは readline を使用します。これは、履歴と基本的な補完機能を備えています。詳細な理解を得るには、ソースを検査できます。さらに、readlineを使用して、完成した独自のCLIインターフェイスを構築できます。