Bashプログラミング
 Computer >> コンピューター >  >> プログラミング >> Bashプログラミング

LinuxのBash補完を強化する!completeコマンドで実現する便利な自動補完テクニック10選

Linuxでは、コマンド入力中にTABキーを2回押すと、入力した文字で始まる利用可能なコマンドがすべて一覧表示されます。

これはおそらくご存知の方も多いでしょう。この機能は「bash補完(bash completion)」と呼ばれ、ファイル名やディレクトリ名の基本的な補完は、Bashのコマンドラインでデフォルトで利用できます。

しかし、completeコマンドを使えば、このbash補完をさらに強力にし、次のレベルへ引き上げることが可能です。

本記事では、「プログラマブル補完(programmable completion)」を使って、コマンドのオプションや引数に自動補完を適用する方法を詳しく解説します。

プログラマブル補完の例

たとえば、writeコマンドを入力した後にTABキーを2回押すと、書き込み操作の対象となるユーザーの一覧が自動補完されます。

$ write [TAB][TAB]
bala      raj
jason     randy
john      ritu
mayla     thomas
nisha     www-data

次の例では、telnetコマンドに対して利用可能なホスト名が表示されます。

$ telnet [TAB][TAB]
localhost  dev-db  fileserver

プログラマブル補完を有効にする方法

ターミナルでプログラマブル補完を有効にするには、以下のように /etc/bash_completion を読み込むだけでOKです。

# . /etc/bash_completion

また、Ubuntu Linux 13.04以降では、/etc/bash.bashrc 内の以下の行のコメントアウトを解除しておけば、上記のコマンドを毎回実行する必要がなくなります。

# enable bash completion in interactive shells
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

もし上記の行や /etc/bash_completion ファイルが見つからない場合は、apt-getで bash_completion パッケージをインストールしてください。

1. 既存のbash補完設定を確認する

プログラマブルbash補完を有効にすると、あらかじめ定義された一連の補完ルールが存在します。bash補完の定義には complete コマンドを使用します。

既存のbash補完を確認するには、以下のように complete コマンドを実行します。

complete -p | less

なお、上記の例ではオプション -p は省略可能です。

2. Bashの標準補完の一覧

Bashはデフォルトで、Linuxユーザー向けに以下の標準補完を提供しています。

  1. 変数名の補完
  2. ユーザー名の補完
  3. ホスト名の補完
  4. パス名の補完
  5. ファイル名の補完

これらについては、以前のBash標準補完に関する記事でも詳しく取り上げています。

3. コマンド一覧を取得する補完を定義する

-c オプションを付けて補完を定義すると、利用可能なコマンドの一覧を引数として取得できるようになります。次の例では、which コマンドに対して補完を定義しています。

$ complete -c which

$ which [TAB][TAB]
Display all 2116 possibilities? (y or n)

上記のように、「y」を押すとすべてのコマンドが一覧表示されます。

4. ディレクトリのみを取得する補完を定義する

-d オプションを使うと、ディレクトリ名だけを引数として取得する補完を定義できます。次の例では、ls コマンドに対して補完を定義しています。

$ ls
countfiles.sh  dir1/          dir2/          dir3/

$ complete -d ls

$ ls [TAB][TAB]
dir1/          dir2/          dir3/

このように、TABキーを押すとディレクトリのみが表示されます。

5. バックグラウンドジョブ名を取得する補完を定義する

complete を使えば、ジョブ名をコマンドの引数として取得することも可能です。-j オプションを使うと、以下のようにジョブ名を引数として渡せます。

$ jobs
[1]-  Stopped                 cat
[2]+  Stopped                 sed 'p'

$ complete -j ./list_job_attrib.sh

$ ./list_job_attrib.sh [TAB][TAB]
cat   sed

バックグラウンドジョブについて言えば、これらの例を使ったLinuxバックグラウンドジョブの管理方法も合わせて知っておくと便利です。

6. 接頭辞と接尾辞を付けた補完

補完の定義には、実際の補完候補に追加したい接頭辞(prefix)と接尾辞(suffix)を指定することもできます。次の例では、list_job_attrib.sh に対して接頭辞と接尾辞を定義しています。

$ jobs 
[1]+  Stopped                 cat

$ complete -P '">' -S '<"' ./list_job_attrib.sh

$ ./list_job_attrib.sh [TAB][TAB]

$ ./list_job_attrib.sh ">cat<"

7. 特定ファイルを除外したファイル・ディレクトリ補完

スクリプトの実行結果がoutputディレクトリに出力されるケースを考えてみましょう。

$ cd output/

$ ls
all_calls.txt   incoming_calls.txt   outgoing_calls.txt   missed_calls.txt
parser_mod.tmp  extract.o

上記の状態で、ls コマンドの自動補完時に .tmp ファイルと .o ファイルを除外したい場合は、以下のようにします。

$ export FIGNORE='.tmp:.o'

$ complete -f -d ls

$ cd output

$ ls [TAB][TAB]
all_calls.txt   incoming_calls.txt   outgoing_calls.txt   missed_calls.txt

FIGNORE は、除外対象となるファイル名の接尾辞を格納するシェル変数で、ここに指定された拡張子は自動補完の候補から除外されます。

8. IFSで文字列を分割して補完値を取得する

-W オプションで単語リスト(wordlist)を指定すると、そのリストはIFS変数の値で分割されます。分割された各単語は展開され、補完候補として表示されます。

$ export IFS=" "

$ complete -W "bubble quick" ./sort_numbers.sh

$ ./sort_numbers.sh [TAB][TAB]
bubble   quick

上記のように、IFS区切り文字で文字列を分割した後、単語が展開されるため、以下のように変数を指定することも可能です。

$ echo $SORT_TYPE1
bubble

$ echo $SORT_TYPE2
quick

$ complete -W "$SORT_TYPE1 $SORT_TYPE2" ./sort_numbers.sh
$ ./sort_numbers.sh [TAB][TAB]
bubble   quick

9. 独自の関数を作成して補完を生成する

補完の定義に関数を組み込むこともできます。-F オプションで関数名を complete コマンドに渡すと、その関数が実行されて補完候補が生成されます。たとえば、以下のような関数を記述します。

_parser_options()
{
  local curr_arg;

  curr_arg=${COMP_WORDS[COMP_CWORD]}

  COMPREPLY=( $(compgen -W '-i --incoming -o --outgoing -m --missed' -- $curr_arg ) );
}

この関数内で使われている要素は以下のとおりです。

  1. COMPREPLY: 補完結果を保持する配列。[TAB][TAB]を押した後に表示される内容です。
  2. COMP_WORDS: コマンドラインに入力された単語の配列です。
  3. COMP_CWORD: COMP_WORDS配列のインデックス。これを使ってコマンドライン上の異なる位置の単語にアクセスできます。
  4. compgen: -W に補完候補の可能性を保持し、$curr_argに基づいて該当する引数が選択されます。

この関数が含まれるファイル parser_option を、以下のように読み込み(source)ます。

$ source parser_option

そして、この関数をパーサースクリプトに紐付けます。

$ complete -F _parser_options ./parser.pl

$ ./parser.pl [TAB][TAB]
-i       --incoming       -o       --outgoing       -m       --missed

上記のように、パーサーのオプションが _parser_options() 関数によって生成されていることがわかります。

注: プログラマブル補完用の関数をもっと見たい場合は、/etc/bash_completion ファイルを参照してください。

10. 一次補完で候補がない場合の二次スペックを指定する

定義した補完仕様から一致する候補が1つも生成されなかった場合、-o オプションで指定したcomp-optionが補完に使用されます。

$ complete -F _count_files -o dirnames ./countfiles.sh

上記の例では、ファイル ./countfiles.sh の補完が _count_files 関数によって定義されています。もし _count_files() 関数が何も一致候補を生成しなかった場合は、ディレクトリ補完が試みられます。

$ ls 
countfiles.sh    dir1/      dir2/      dir3/

$./countfiles.sh [TAB][TAB]
dir1    dir2    dir3
  1. Linuxで効果的なBashスクリプトを書くための実践テクニック10選

    シェルスクリプトは、Linuxで学べる最も手軽なプログラミング手法のひとつです。システム管理におけるタスクの自動化や、簡単なユーティリティ・ツールの開発など、管理者にとって必須のスキルとも言えます。 本記事では、効果的かつ信頼性の高いbashスクリプトを書くために役立つ、実用的な10のヒントを紹介します。 1. スクリプトには必ずコメントを書く これはシェルスクリプトに限らず、あらゆるプログラミングで推奨される基本プラクティスです。コメントを適切に記述しておけば、後から自分や他の人がスクリプトを読んだときに、各部分が何をしているのかを素早く理解できます。 コメントは # 記号で定義します。 #

  2. Linuxのwatchコマンドの使い方と実用例をわかりやすく解説

    Linuxのwatchコマンドは、指定したコマンドを一定間隔で繰り返し実行し、その結果を画面に表示し続けるためのツールです。コマンドの出力が時間とともにどう変化するかをリアルタイムで監視したい場合に非常に便利です。この記事では、watchコマンドの基本的な使い方と、覚えておくと役立つ実用的な例を紹介します。 watchコマンドの基本構文 watchコマンドの構文は以下のとおりです。 watch オプション コマンド 各要素の意味は次のとおりです。 オプション: 後述の表から選択したオプションを指定します。watchコマンドのデフォルト動作を変更できます。 コマンド: watchが繰り返し実行