Next: , Previous: Single File, Up: Run Commands


3.3.2 複数のファイル

一度に一つずつのファイルを処理する必要がある時もあります.しかし,これ は不要で,ファイルごとにコマンドを実行するより,できるだけ多くのファイ ルをコマンドで実行した方が速くなります.こうすることで,それぞれのコマ ンドを開始する時間を稼ぐことになります.

-execdir’と‘-exec’アクションには,できるだけ多くのマッチした ファイルを含むコマンドラインを構築する亜種があります.

— Action: -execdir command {} +

これは‘-execdir command ;’と同じように動作しますが,コマンドの終わ りの‘{}’はマッチしたファイルの名前のリストになります.この展開は, システムで利用可能なコマンドラインの最大の長さを越えないように行われま す.コマンドには一つの‘{}’だけが可能で,‘+’の直前に,最後に 書く必要があります.‘{}’直後以外の位置にある‘+’は,特別扱い されません(つまり,コマンドの終端ではありません).

— Action: -exec command {} +

この,余りセキュリティーの高くない‘-execdir’アクションの亜種は, POSIXで指定されているものです.主な違いは,findが呼び出されたディ レクトリでコマンドが実行されるということで,‘{}’が,マッチしたファ イルのベース名ではなく,開始ディレクトリからの相対パスに展開されること を意味します.

findが終了する前に,部分的に構築されたコマンドラインが実行されま す.これは,‘-quit’アクションで終了された場合もそうなります.しか し,エラーの形式によっては(例えばstat()の呼び出しがカレントディ レクトリで不可能),直後に致命的な終了になります.この状況では,部分的に 構築されたコマンド莱因は呼び出されません(これで,無限ループを抑止しま す).

もう一つの,余りセキュリティは高くありませんが,一度に一つ以上のファイ ルでコマンドを実行する方法は,xargsコマンドを使用する方法で,以 下のように呼び出します.

     xargs [option...] [command [initial-arguments]]

xargsは通常,標準入力から引数を読み込みます.これらの引数は空白 (それは,ダブルクオートやシングルクオートまたはバックスラッシュで保護可 能)や改行で分離されています.それはcommand (デフォルトで /bin/echo)を,標準入力から読み込まれた引数が続くあらゆる initial-argumentsを用いて,一回以上実行します.標準入力の空白行は 無視されます.

空白の分離名の代わりに,‘find -print0’や‘find -fprint0’を使用 し,GNU xargs,GNU tar,GNU cpio,または perlへ,‘-0’や‘--null’オプションを与えて,出力を処理し た方が安全です.locateコマンドにも,同じことを行う‘-0’や ‘--null’オプションがあります.

以下のように,引数リストを処理するためシェルコマンドの置換(バッククオー ト)を使用することが可能です.

     grep -l sprintf `find $HOME -name '*.c' -print`

しかし,その方法は,‘.c’ファイル名の長さが,オペレーティングシステ ムのコマンドラインの長さの制限を超過する場合,エラーが生じるでしょう. xargsは,制限を超過しないようにするために必要なだけコマンドを実 行することで,その問題を避けます.

     find $HOME -name '*.c' -print | xargs grep -l sprintf

しかし,標準入力が端末であることを必要とするコマンド(例えば, less)の場合,シェルコマンドの置換の手法や,xargsの ‘--arg-file’オプションを使用する必要があります.

xargsコマンドは,コマンドが255のステータスで終了したり (xargsがエラーメッセージを出力し停止しています),ファイルの終 わりとなる‘--eof’オプションで指定されている文字列を含んでいる行を 読み込むまでは,すべての入力を処理し,コマンドラインを構築し,それを実 行します.