カスタムスクリプトの自動補完を追加する

カスタムスクリプトの自動補完を追加する

私は現在、 と呼ばれるシェル スクリプトmakeyourself.sh( にリンク) に取り組んでいます。このスクリプトは、ソース ( 経由)/usr/bin/mysから Debian パッケージを自動的にインストールします。apt-get source -b $1

そこで、最初のパラメータとして指定されるパッケージ名のオートコンプリート機能を追加することにしました。sudo mys panth<tab><tab>これで、で始まるすべてのパッケージがリストされるはずですpanth。私の試みは次のようになりました。

complete -C "apt-cache --no-generate pkgnames" mys

しかし、うまくいかないようです。上記のように Tab キーを押すと、 はパラメータを に変更しmys、 を返しますsudo mys mys

何が間違っているのでしょうか? またはのcompleteように、補完される文字列を挿入するコマンド内の場所を指定する必要がありますか?{}$1

私はUbuntuをベースにしたLinuxディストリビューションであるElementaryOSを使用しています。スクリプトは標準の*.shシェルスクリプトで、標準の#!/bin/bash

答え1

ご想像のとおり、コマンドは完了すべき内容に関する情報を受け取ります。これはマニュアルに記載されていますが、complete組み込みのドキュメント、読む必要がありますプログラム可能な完了に関する導入セクション

-Fおよびオプションで指定されたシェル関数またはコマンド-Cが呼び出されます。コマンドまたは関数が呼び出されると、、、、およびCOMP_LINE変数に上記のように値が割り当てられます(COMP_POINTCOMP_KEYCOMP_TYPEBash 変数) シェル関数が呼び出される場合は、COMP_WORDSおよびCOMP_CWORD変数も設定されます。関数またはコマンドが呼び出されると、最初の引数は引数が補完されるコマンドの名前、2 番目の引数は補完される単語、3 番目の引数は現在のコマンド ラインで補完される単語の前の単語です。補完される単語に対して生成された補完のフィルタリングは実行されません。関数またはコマンドは、一致を生成する際に完全に自由に使用できます。

したがって、コマンドは次の 3 つのパラメータで呼び出されます。

  • コマンド名 - 1 つのスクリプト内で類似のコマンドの補完を組み合わせることができます。
  • 補完する単語。いずれにせよフィルタリングされる接頭辞に出力を制限できます。
  • 前の単語 — オプションを完了する場合などに便利です。

同じパラメータが補完関数 ( complete -F somefunction) に渡されます。関数を使用する場合もコマンドを使用する場合も、必要な一致をフィルタリングするのはユーザーの仕事であることに注意してください。

あなたが試したことでは、最終的に実行されるコマンドは です。これは、 (は最初のオペランドのみを参照)apt-cache --no-generate pkgnames mys '' mysで始まるパッケージ名のリストを出力します。最も長い共通プレフィックスは であるため、bash は補完を開始し、次の文字を選択することを期待します。mysapt-cache pkgnamesmysmys

引数がコマンドに追加される(位置パラメータとして渡されるのではなく、引数は-Cシェル コマンドとして解析される)ため、引数を解析する簡単な方法はありません。最も簡単な解決策は、ラッパー関数を使用することです。

_mys () {
  COMPREPLY=$(apt-cache --no-generate pkgnames "$2")
}
complete -F _mys mys

関連情報