コマンド | 説明 |
---|---|
xargs | 標準入力でリストを受け取り、単一の引数に分割して各引数に対しコマンドを実行する |
% find . -name '*.php' | xargs -i cp {} ~/backup-i : {} を引数リストに置き換える
% find . -type f -name '*.bak' -print0 | xargs -0 rmfind -print0
ファイル名をフルパスで標準出力に表示し、各ファイル名にNULL文字を付加する。 このオプションは最後に付ける。
xargs -0, --null
標準入力からの文字列の区切りに、空白ではなくヌル文字が使われているとみなす。 また引用符やバックスラッシュに特別の意味を持たせず、すべての文字をそのまま用いる。 ファイル終了文字列も無効となり、他の文字列と同じように扱われる。 入力される文字列に空白・引用符・バックスラッシュが含まれている場合に有用である。
find の -print0 オプションと xargs の -0 オプションを指定することで、ファイル名に改行やスペースが混入しているファイルでも正しく削除できる。 |
---|
% find baddir | xargs -r grep 'hoge'-r : 入力を受け取らなかったときにコマンドを実行しない
Argument list too long
このエラーは、コマンドの引数があまりにも長いために起こるエラーです。 コマンドに指定できる引数の長さは有限です。どの位まで許容されているかは不明ですが。。
% find /path/to/dir -type f | xargs sudo chown hoge:fuga sudo: unable to execute /bin/chown: Argument list too long
一旦 cd して、引数の長さを短くすることで対応できる場合もあります。
% cd /path/to/dir; find . -type f | xargs sudo chown hoge:fuga
A と B で実際に実行される chown は下記のイメージです。
chown hoge:fuga /path/to/dir/file1 /path/to/dir/file2 /path/to/dir/file3 ...
chown hoge:fuga file1 file2 file3 ...
A より B の方が、引数の文字数が少なくて済みますね。
B の方法でも「Argument list too long」が発生する場合は、下記 C で対処します。
xargs に iオプションを指定する
% find /path/to/dir -type f | xargs -i sudo chown hoge:fuga '{}'
iオプションを指定することで、後方の '{}' にパイプで渡ってきたファイルパスが置換されます。
そして置換された個々のファイルに chown コマンドが適用されます。
これで「Argument list too long」の問題は解決します。
解説 |
---|
上記 C は、個々のファイル毎に chown コマンドを適用するので、速度的には遅くなるので注意が必要です。
通常の xargs では、与えられた複数のファイルパスに対して1回のコマンドで処理を行うため、とても高速です。
chown hoge:fuga /path/to/dir/file1 /path/to/dir/file2 /path/to/dir/file3 ...
chown hoge:fuga /path/to/dir/file1 chown hoge:fuga /path/to/dir/file2 chown hoge:fuga /path/to/dir/file3 :
xargs を使わずに find コマンドの -exec オプションを利用する
% find . -type f -exec sudo chown chown hoge:fuga {} \;