web-dev-qa-db-ja.com

findコマンドの-execで2つのbashコマンドを使用するにはどうすればよいですか?

findコマンドの-exec部分で2つのコマンドを使用することは可能ですか?

私は次のようなことを試しました:

find . -name "*" -exec  chgrp -v new_group {}  ; chmod -v 770 {}  \;

そして私は得る:

find:-execの引数がありません
chmod:アクセスできません{}:そのようなファイルまたはディレクトリはありません
chmod:アクセスできません;:そのようなファイルまたはディレクトリはありません

33
Luc M

findコマンドについては、さらに-execコマンドを続けて追加することもできます。

find . -name "*" -exec chgrp -v new_group '{}' \; -exec chmod -v 770 '{}' \;

このコマンドは、その結果では、

chgrp -v new_groupファイル&& chmod -v 770ファイル

各ファイルに。

-name-exec-sizeなどのすべてのfindのパラメーターは、実際にはtestsです:findはこれまでにチェーン全体がtrueと評価されている限り、それらを1つずつ実行し続けます。したがって、連続する各-execコマンドが実行されます次の場合のみ前のコマンドが返されますtrue(つまり、0コマンドの終了ステータス) 。ただし、findは、or-o)およびnot!)。したがって、前の結果の-execテストの連鎖に関係なくを使用するには、次のようなものを使用する必要があります。

find . -name "*" \( -exec chgrp -v new_group {} \; -o -exec chmod -v 770 {} \; \)
47
rozcietrzewiacz
find . -name "*" -exec sh -c 'chgrp -v new_group "$0" ; chmod -v 770 "$0"' {} \;
17
glenn jackman

コマンドは最初にシェルによって解析され、_;_で区切られた2つのコマンドに変換されます。これは改行に相当します。

_find . -name "*" -exec chgrp -v new_group {}
chmod -v 770 {} \;
_

シェルコマンドを実行する場合は、_bash -c_(またはシェルが特にbashであるかどうかを気にしない場合は_sh -c_)を使用してシェルを明示的に呼び出します。

_find . -name "*" -exec sh -c 'chgrp -v new_group "$0"; chmod -v 770 "$0"' {} \;
_

シェルの引数として_{}_を使用していることに注意してください。これは0番目の引数(通常はシェルまたはスクリプトの名前ですが、ここでは関係ありません)であるため、_"$0"_として参照されます。

一度に複数のファイル名をシェルに渡し、シェルにそれらを反復させることができます。これにより高速になります。ここでは、スクリプト名として___を渡します。次の引数はファイル名であり、_for x_(_for x in "$@"_のショートカット)が繰り返し処理されます。

_find . -name "*" -exec sh -c 'for x; do chgrp -v new_group "$x"; chmod -v 770 "$x"; done' _ {} +
_

Bash 4またはzshでは、ここで検索する必要がないことに注意してください。 bashで_shopt -s globstar_を実行し(_~/.bashrc_に入れて)、再帰的なディレクトリグロブを表す_**/_をアクティブにします。 (zshでは、これは常にアクティブです。)

_chgrp -v new_group -- **/*; chmod -v 770 -- **/*
_

または、ファイルを順番に繰り返し処理する場合

_for x in **/*; do
  chgrp -v new_group -- "$x"
  chmod -v 770 -- "$x"
done
_

findコマンドとの1つの違いは、シェルがドットファイル(名前が_._で始まるファイル)を無視することです。それらを含めるには、bashで最初に_GLOBIGNORE=.:.._を設定します。 zshでは、グロブパターンとして**/*(D)を使用します。