SSブログ

Unix系コマンドのワイルドカード(*)にご注意?! find/xargsを使おう [Solaris]

久しぶりにSolarisのコマンドでハマリましたので、Tipsで残しておきます。

ログファイルを格納しているディレクトリに対して、ls -l *.logって実行すると「Argument list too long.」 や「引数が多すぎます 」、「引数リストが長すぎます」などとエラーになります。

これは、ワイルドカード(*)がシェルの内部処理によって展開され、コマンドラインのサイズをオーバーしてしまうかです。例えば、a.logとb.logの2つのファイルが存在し、ls -l *.logとすると、ファイル名展開により、ls -l a.log b.logになります。シェルが展開した文字数は、OS毎に制限があり、solarisでは1MB(1,048,320)、Linux(Ubuntu10.10)では2MB(2,097,152)になっています。

使っているOSのARG_MAXを参照すれば、コマンドラインサイズがわかります。
% getconf ARG_MAX

では、コマンドラインサイズを超えてしまうls -l *.logをどのようにすれば、できるのでしょうか。
①findを使う
find . -name \*.log -exec ls -l {} \;
(-execでは1ファイル毎にls -lが行われるため、非常に遅い)

②find+xargsを使う
find . -name \*.log | xargs ls -l

③grepを使う
ls -l | grep .log

lsで表示できたものを削除したい場合には、rm *.logとしたいところですが、これもエラーになります。こんなときは、xargsを使うと効率的にrmができます。

①xargsを使ってrmする
ls | grep .log | xargs rm
または
find . -name \*.log | xargs rm

②findを使ってrmする
find . -name \*.log -exec rm {} \;
(1ファイル毎にrmが行われるため、非常に遅い)

同様にtarでまとめたい時もxargsを使うと効率的に可能です。
①xargsを使ってtarする
ls | grep .log | xargs tar rvf /tmp/logs.tar
または
find . -name \*.log |xargs tar rvf /tmp/logs.tar

②findを使ってtarする
find . -name \*.log -exec tar rvf /tmp/logs.tar {} \;
(1ファイル毎にrmが行われるため、非常に遅い)

最近では、コマンドラインサイズも大きくなってきているので、エラーになる確率も減っていると思います。
xargsをうまく使うことで、処理時間の短縮が図れますので、是非xargsをご利用ください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。