completeコマンドは、bashの組み込みコマンドになります。シェルでは入力途中の文字に対してTABを入力すると入力補完機能が働きます。completeコマンドはこの入力補完機能をどのように表示するかを設定できます。
目次
completeコマンドの構文
completeコマンドの簡単な構文
1 |
complete [option...] [name ...] |
name:
completeコマンドで補完機能を適用する名前。nameは基本的にコマンドやファイル名を設定し、シェルでnameを入力した後にTabを入力するとcompleteコマンドで設定した補完が表示されます。
compspecを確認
completeコマンドを引数なしで用いるとcompleteコマンドで設定されている補完仕様(completion specification,compspec)を確認できます。
実行結果では、私の環境で端末の起動時にデフォルトで設定されるcompspecを7つランダムに表示させています。
コマンド例と実行結果
1 2 3 4 5 6 7 8 |
$complete | shuf | head -n7 complete -F _longopt uniq complete -F _longopt du complete -F _service /etc/init.d/apparmor complete -F _filedir_xspec kwrite complete -d pushd complete -F _longopt env complete -F _service /etc/init.d/ufw |
また、個別にcompspecを確認する場合は-pオプションを利用します。
コマンド例と実行結果
1 2 3 |
$complete -p uniq du complete -F _longopt uniq complete -F _longopt du |
compspecを設定
compspecを設定する場合は、completeコマンドの引数に補完を行うコマンド名を指定します。
ここでは、echoコマンドに対する補完で、組み込みコマンドの名前が補完される設定(-bオプション)を行っています。基本的な補完機能はコマンドの後にスペースを置いた後にTabを入力することで表示されます。
コマンド例と補完結果
1 2 3 4 5 6 7 8 9 10 11 |
$complete -b echo $echo . cd echo getopts mapfile set type : command enable hash popd shift typeset [ compgen eval help printf shopt ulimit alias complete exec history pushd source umask bg compopt exit jobs pwd suspend unalias bind continue export kill read test unset break declare false let readarray times wait builtin dirs fc local readonly trap caller disown fg logout return true |
compspecのリストにない時に動作するデフォルトのcompspecは-Dオプションを用いると設定できます。
コマンド例
1 |
complete -b -D |
また、何も入力が行われていないときに動作するcompspecは-Eオプションを用いると設定できます。
コマンド例
1 |
complete -b -E |
補完オプションを設定
(-oオプション)
-oオプションにオプションを指定して利用すると補完の動作を少し変更できます。
補完オプションの種類
オプション | 意味 |
default | Readlineのデフォルトのファイル名の補完 |
bashdefault | 変数($で始まるテキスト)、ユーザ名(~で始まるテキスト)、 ホスト名(@で始まるテキスト)などの他のbashデフォルト補完 |
dirnames | ディレクトリ名の補完 |
filenames | -Fオプションでcompspecをファイル名の生成として処理 (ディレクトリ名に/を追加や末尾のスペースの抑制などが行われる) |
noquote | ファイル名ならばクォートしない |
nospace | 補完された単語の終わりにスペースを追加しない |
plusdirs | 補完リストにディレクトリ名が存在する場合、ディレクトリ名の処理を行う |
コマンド例
1 |
complete -o default -D |
パターンが決まっているリストを補完候補に追加
(-Aオプション)
-Aオプションにアクションを指定して用いると簡易的に補完候補を追加できます。また、いくつかのアクションには同等なオプションがあります。
アクションの種類
アクション | 意味 | オプション |
alias | エイリアス(別名) | -a |
arrayvar | 配列変数 | |
binding | Readlineのキー・バインド名 | |
builtin | 組み込みコマンド | -b |
command | コマンド | -c |
directory | ディレクトリ名 | -d |
disabled | 無効な組み込みコマンド | |
enabled | 有効な組み込みコマンド | |
export | 環境変数 | -e |
file | ファイル名 | -f |
function | シェルの関数名 | |
group | グループ名 | -g |
helptopic | helpコマンドでのトピック | |
hostname | ホスト名 (変数HOSTFILEの内容や/etc/hostsが参照) | |
job | ジョブ名 | -j |
keyword | シェルの予約語 | -k |
running | 動作中のジョブ名 | |
service | サービス名 | -s |
setopt | setコマンドの-oオプションの引数 | |
shopt | shoptコマンドのオプション名 | |
signal | シグナル名 | |
stopped | 停止中のジョブ名 | |
user | ユーザ名 | -u |
variable | シェルの変数名 | -v |
コマンド例と補完結果
1 2 3 4 5 6 7 8 9 10 11 |
$complete -A builtin echo $echo . cd echo getopts mapfile set type : command enable hash popd shift typeset [ compgen eval help printf shopt ulimit alias complete exec history pushd source umask bg compopt exit jobs pwd suspend unalias bind continue export kill read test unset break declare false let readarray times wait builtin dirs fc local readonly trap caller disown fg logout return true |
単純なリストを補完候補に追加
(-Wオプション)
-Wオプションは単語のリストを指定することで、単純なリストを補完候補に追加できます。単語のリストの区切り文字は変数IFSが使用されます。
コマンド例と補完結果
1 2 3 |
$complete -W 'aaa bbb ccc' echo $echo aaa bbb ccc |
コマンドの出力を補完候補に追加
(-Cオプション)
-Cオプションを用いるとサブシェル環境で実行されるコマンドの出力を補完候補に追加できます。補完候補はコマンドの出力の一行ごとになります。
-Cオプションで設定されるコマンド文字列には自動的に引数が追加されます。第1引数にコマンドの名前、第2引数に補完中の単語、第3引数に補完中の単語の前の単語が設定されます。
例えば、
1 |
$complete -C 'printf "1:%s,2:%s,3:%s\n"' echo |
のコマンドを実行した後に、
1 |
$echo aa bb cc |
のccの単語に対して、補完機能を実行するためにTabを入力すると、
1 |
$echo aa bb 1:echo,2:cc,3:bb |
と補完され、-Cオプションで指定したコマンドに対して、引数が追加されるのが分かります。
追加される引数が必要ない場合などはコマンドを;で区切り、末尾に:(ヌルコマンド)を追加する等を行うとコマンドに追加される引数の意味をなくすことができます。
1 2 3 |
$complete -C 'printf "aa\nbb\ncc\n" ;:' echo $echo aa bb cc |
関数を用いて補完候補に追加
(-Fオプション)
-Fオプションで関数を指定するとその関数を用いて補完候補を追加することができます。
補完候補は配列変数COMPREPLYに追加します。
関数の引数として第1引数にコマンドの名前、第2引数に補完中の単語、第3引数に補完中の単語の前の単語が設定されます。
ここでは、簡単な例としてechoコマンドに用いる補完関数をfunc.shに作成します。
補完関数の名前は_echoとして、echoコマンドに対して、-nオプションが直前にある場合は組み込みコマンドを、それ以外の場合はhelpコマンドで参照できるコマンドを補完候補として表示します。
func.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 |
_echo () { local cur prev result cur="$2" prev="$3" case "$prev" in -n) result=($(compgen -A builtin -- "$cur")) ;; *) result=($(compgen -A helptopic -- "$cur")) ;; esac COMPREPLY=(${result[*]}) } |
compgenコマンドはcompleteコマンドと同じオプションを持ち、completeコマンドで表示される補完候補を出力します。また、compgenコマンドの引数に文字列があると、その文字列に当てはまる補完候補を自動的に絞って出力します。
補完関数を作成する場合の注意点として、変数は他の変数に影響が出ないようにlocalの宣言を用いることを忘れないようにします。
作成したファイルに対して、sourceコマンド又は.(ドットコマンド)を用いて、関数を読み込み、completeコマンドで関数を指定すると、独自に作成した補完を行うことができます。
関数を用いた補完を行うと、オプションによって補完方法が変更される柔軟な補完を行うことができます。
コマンド例と補完結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
$ls func.sh $. func.sh $complete -F _echo echo $echo % break dirs function popd source unset (( builtin disown getopts printf suspend until )) caller echo hash pushd test variables . case enable help pwd time wait ... cd eval history read times while : command exec if readarray trap { [ compgen exit jobs readonly true } [[ complete export kill return type ]] compopt false let select typeset alias continue fc local set ulimit bg coproc fg logout shift umask bind declare for mapfile shopt unalias $echo -n . cd echo getopts mapfile set type : command enable hash popd shift typeset [ compgen eval help printf shopt ulimit alias complete exec history pushd source umask bg compopt exit jobs pwd suspend unalias bind continue export kill read test unset break declare false let readarray times wait builtin dirs fc local readonly trap caller disown fg logout return true |
補完の自作関数作成のヒント
自作で独自のリストから補完を行うような補完関数を作成したい場合は、grepコマンドで補完するリストを絞っていくことで機能を実現できます。
実験的にechoコマンドに補完機能を実装しようとします。
echo_comp.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
__echo_comp_list () { echo -n '''aaa abb bbb ccc ''' } _echo () { local cur prev cur="$2" prev="$3" COMPREPLY=() case "$cur" in *) COMPREPLY=($(__echo_comp_list | grep ^"$cur")) ;; esac } |
echo_comp.shの内容をシェル環境に取り込んで、completeコマンドでその関数を登録し、機能を確認します。
文字を入力してTABを押していき、候補が一つになった時点で自動的にその候補が補完されます。
1 2 3 4 5 6 7 8 9 |
$ source echo_comp.sh $ complete -F _echo echo $ echo aaa abb bbb ccc $ echo bbb aaa abb bbb ccc $ echo bbb a aaa abb $ echo bbb a |
grepコマンドの(^)は正規表現で文字列の最初を意味し、最初の部分からコマンドの現在補完している単語を入れることで候補を絞っています。
1 2 3 4 5 6 7 8 9 10 |
$ __echo_comp_list | grep ^ aaa abb bbb ccc $ __echo_comp_list | grep ^a aaa abb $ __echo_comp_list | grep ^b bbb |
補完する方法については詳しい情報があまり見当たらなかったので、もっと良い方法があるかもしれませんが、とりあえず補完したいものを汎用的に作成したい場合は便利だと思います。
cur変数やprev変数を活用すれば、多少複雑な制御もできると思います。また、bash-completionのヘルパー関数を利用できるともっと良いものにできると思います。
ファイルパターンを用いて補完候補に追加
(-Gオプション)
-Gオプションでファイルパターンを用いると、補完候補にそのファイルパターンのファイル名を追加できます。
コマンド例と補完結果
1 2 3 4 5 6 7 8 |
$touch file{1,2,3}{.txt,.sh,.c,.h} $ls file1.c file1.sh file2.c file2.sh file3.c file3.sh file1.h file1.txt file2.h file2.txt file3.h file3.txt $ $complete -G'*.txt' echo $echo file file1.txt file2.txt file3.txt |
パターンに一致する補完候補を除外
(-Xオプション)
-Xオプションを用いると、補完候補からパターンに一致する補完候補を除外することができます。
コマンド例と補完結果
1 2 3 4 |
$complete -f -X '*.txt' echo $echo file file1.c file1.sh file2.h file3.c file3.sh file1.h file2.c file2.sh file3.h |
また、'!'の記号を用いるとパターンを否定することもできます。
コマンド例と補完結果
1 2 3 |
$complete -f -X '!*.txt' echo $echo file file1.txt file2.txt file3.txt |
補完候補に接尾辞を追加
(-Sオプション)
-Sオプションで文字列を指定すると、補完候補にその文字列を接尾辞として追加することができます。
コマンド例と補完結果
1 2 3 |
$complete -S'.txt' -W 'aaa bbb ccc' echo $echo aaa.txt bbb.txt ccc.txt |
また、-Pオプションで全ての補完リストに接頭辞を追加することもできます。
compspecの削除
(-rオプション)
-rオプションを用いると定義したcompspecを削除できます。引数を指定しなかった場合はすべてのcompspecが削除されます。
コマンド例と実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$complete complete -f -E complete -f -D complete -f echo $ $complete -r -D $complete complete -f -E complete -f echo $ $complete -r $complete $ |