読者です 読者をやめる 読者になる 読者になる

Programming log - Shindo200

イベント参加記録とプログラミング系の雑記

シェル上でのワイルドカードについて

30000個ぐらいのログファイルをまとめて削除するため、下記のコマンドを実行しました。

$ rm *.log

すると、「引数リストが長すぎます」とエラーが表示されました。この問題の解決方法を2つ紹介します。

解決方法

シェルスクリプトで、削除処理を分割する

(ファイル名にパターンがある場合に有効)

$ for i in 2010 2011 2012
do
  rm $i*.log
done

xargs を使って各ファイルに対してコマンドを実行する

$ echo *.log|xargs rm

ここまでのことを書いてある記事はたくさんあるのですが、原因まで書いてある記事はあまり見つからず。原因を探るため、ワイルドカードが何をしているか調べてみます。

ディレクトリに「hoge.log」「fuga.log」「piyo.log」の3つのファイルを作ります。このディレクトリで下記のコマンドを実行します。

$ *.log
hoge.log fuga.log piyo.log

各ファイル名をスペース区切りにした文字列が出力されます。ワイルドカードには、条件に一致したファイルで引数リストを作成する動きがあることがわかります。この結果から、下記の2つのコマンドは同じ動きになることがわかります。

$ rm *.log
$ rm hoge.log fuga.log piyo.log

上記のコマンドを実行すると、正常にファイルが削除されます。しかし、コマンドの引数を増やすとエラーになってしまいます。この現象はrm以外のコマンドでも発生します。
実は、シェルが扱える引数の数には上限があります。この数はシェルによって違います。上限を超えてしまうと「引数リストが長すぎます」とエラーが表示されます。

まとめ

  • 「コマンドの引数をワイルドカードにした場合、一致するファイルを見つけて、各ファイルに対してコマンドを実行する」という処理はしていない。
  • 「コマンドの引数をワイルドカードにした場合、一致するファイルを引数リストにし、コマンドを実行する」が正しい。
  • シェルが扱える引数の数には上限がある。