complete - 補完機能の設定を行う

スポンサーリンク

completeコマンドは、bashの組み込みコマンドになります。シェルでは入力途中の文字に対してTABを入力すると入力補完機能が働きます。completeコマンドはこの入力補完機能をどのように表示するかを設定できます。

スポンサーリンク

completeコマンドの構文

completeコマンドの簡単な構文

name:

completeコマンドで補完機能を適用する名前。nameは基本的にコマンドやファイル名を設定し、シェルでnameを入力した後にTabを入力するとcompleteコマンドで設定した補完が表示されます。

compspecを確認

completeコマンドを引数なしで用いるとcompleteコマンドで設定されている補完仕様(completion specification,compspec)を確認できます。

実行結果では、私の環境で端末の起動時にデフォルトで設定されるcompspecを7つランダムに表示させています。

コマンド例と実行結果

また、個別にcompspecを確認する場合は-pオプションを利用します。

コマンド例と実行結果

compspecを設定

compspecを設定する場合は、completeコマンドの引数に補完を行うコマンド名を指定します。

ここでは、echoコマンドに対する補完で、組み込みコマンドの名前が補完される設定(-bオプション)を行っています。基本的な補完機能はコマンドの後にスペースを置いた後にTabを入力することで表示されます。

コマンド例と補完結果

compspecのリストにない時に動作するデフォルトのcompspecは-Dオプションを用いると設定できます。

コマンド例

また、何も入力が行われていないときに動作するcompspecは-Eオプションを用いると設定できます。

コマンド例

補完オプションを設定
(-oオプション)

-oオプションにオプションを指定して利用すると補完の動作を少し変更できます。

補完オプションの種類

オプション意味
defaultReadlineのデフォルトのファイル名の補完
bashdefault変数($で始まるテキスト)、ユーザ名(~で始まるテキスト)、
ホスト名(@で始まるテキスト)などの他のbashデフォルト補完
dirnamesディレクトリ名の補完
filenames-Fオプションでcompspecをファイル名の生成として処理
(ディレクトリ名に/を追加や末尾のスペースの抑制などが行われる)
noquoteファイル名ならばクォートしない
nospace補完された単語の終わりにスペースを追加しない
plusdirs補完リストにディレクトリ名が存在する場合、ディレクトリ名の処理を行う

コマンド例

パターンが決まっているリストを補完候補に追加
(-Aオプション)

-Aオプションにアクションを指定して用いると簡易的に補完候補を追加できます。また、いくつかのアクションには同等なオプションがあります。

アクションの種類

アクション意味オプション
aliasエイリアス(別名)-a
arrayvar配列変数 
bindingReadlineのキー・バインド名 
builtin組み込みコマンド-b
commandコマンド-c
directoryディレクトリ名-d
disabled無効な組み込みコマンド 
enabled有効な組み込みコマンド 
export環境変数-e
fileファイル名-f
functionシェルの関数名 
groupグループ名-g
helptopichelpコマンドでのトピック 
hostnameホスト名
(変数HOSTFILEの内容や/etc/hostsが参照)
 
jobジョブ名-j
keywordシェルの予約語-k
running動作中のジョブ名 
serviceサービス名-s
setoptsetコマンドの-oオプションの引数 
shoptshoptコマンドのオプション名 
signalシグナル名 
stopped停止中のジョブ名 
userユーザ名-u
variableシェルの変数名-v

コマンド例と補完結果

単純なリストを補完候補に追加
(-Wオプション)

-Wオプションは単語のリストを指定することで、単純なリストを補完候補に追加できます。単語のリストの区切り文字は変数IFSが使用されます。

コマンド例と補完結果

コマンドの出力を補完候補に追加
(-Cオプション)

-Cオプションを用いるとサブシェル環境で実行されるコマンドの出力を補完候補に追加できます。補完候補はコマンドの出力の一行ごとになります。

-Cオプションで設定されるコマンド文字列には自動的に引数が追加されます。第1引数にコマンドの名前、第2引数に補完中の単語、第3引数に補完中の単語の前の単語が設定されます。

例えば、

のコマンドを実行した後に、

のccの単語に対して、補完機能を実行するためにTabを入力すると、

と補完され、-Cオプションで指定したコマンドに対して、引数が追加されるのが分かります。

追加される引数が必要ない場合などはコマンドを;で区切り、末尾に:(ヌルコマンド)を追加する等を行うとコマンドに追加される引数の意味をなくすことができます。

関数を用いて補完候補に追加
(-Fオプション)

-Fオプションで関数を指定するとその関数を用いて補完候補を追加することができます。
補完候補は配列変数COMPREPLYに追加します。

関数の引数として第1引数にコマンドの名前、第2引数に補完中の単語、第3引数に補完中の単語の前の単語が設定されます。

ここでは、簡単な例としてechoコマンドに用いる補完関数をfunc.shに作成します。
補完関数の名前は_echoとして、echoコマンドに対して、-nオプションが直前にある場合は組み込みコマンドを、それ以外の場合はhelpコマンドで参照できるコマンドを補完候補として表示します。

func.sh

compgenコマンドはcompleteコマンドと同じオプションを持ち、completeコマンドで表示される補完候補を出力します。また、compgenコマンドの引数に文字列があると、その文字列に当てはまる補完候補を自動的に絞って出力します。

補完関数を作成する場合の注意点として、変数は他の変数に影響が出ないようにlocalの宣言を用いることを忘れないようにします。

作成したファイルに対して、sourceコマンド又は.(ドットコマンド)を用いて、関数を読み込み、completeコマンドで関数を指定すると、独自に作成した補完を行うことができます。
関数を用いた補完を行うと、オプションによって補完方法が変更される柔軟な補完を行うことができます。

コマンド例と補完結果

補完の自作関数作成のヒント

自作で独自のリストから補完を行うような補完関数を作成したい場合は、grepコマンドで補完するリストを絞っていくことで機能を実現できます。
実験的にechoコマンドに補完機能を実装しようとします。

echo_comp.sh

echo_comp.shの内容をシェル環境に取り込んで、completeコマンドでその関数を登録し、機能を確認します。
文字を入力してTABを押していき、候補が一つになった時点で自動的にその候補が補完されます。

grepコマンドの(^)は正規表現で文字列の最初を意味し、最初の部分からコマンドの現在補完している単語を入れることで候補を絞っています。

補完する方法については詳しい情報があまり見当たらなかったので、もっと良い方法があるかもしれませんが、とりあえず補完したいものを汎用的に作成したい場合は便利だと思います。
cur変数やprev変数を活用すれば、多少複雑な制御もできると思います。また、bash-completionのヘルパー関数を利用できるともっと良いものにできると思います。

ファイルパターンを用いて補完候補に追加
(-Gオプション)

-Gオプションでファイルパターンを用いると、補完候補にそのファイルパターンのファイル名を追加できます。

コマンド例と補完結果

パターンに一致する補完候補を除外
(-Xオプション)

-Xオプションを用いると、補完候補からパターンに一致する補完候補を除外することができます。

コマンド例と補完結果

また、'!'の記号を用いるとパターンを否定することもできます。

コマンド例と補完結果

補完候補に接尾辞を追加
(-Sオプション)

-Sオプションで文字列を指定すると、補完候補にその文字列を接尾辞として追加することができます。

コマンド例と補完結果

また、-Pオプションで全ての補完リストに接頭辞を追加することもできます。

compspecの削除
(-rオプション)

-rオプションを用いると定義したcompspecを削除できます。引数を指定しなかった場合はすべてのcompspecが削除されます。

コマンド例と実行結果

参考

Bash Reference Manual