find -execとxargsを介した配管の動作は異なります。

find -execとxargsを介した配管の動作は異なります。

chmod go+w隠しファイルを含む特定のフォルダで再帰的に実行したいのですが、最初に試しました。

find . -name ".*" -o -name "*" -exec chmod go+w {} \;

しかし、隠されたファイルには影響しないことがわかりました。私自身を確認するために走った。

find . -name ".*" -o -name "*"

隠しファイルを一覧表示します。また、そのセクションを除外すると、隠されたファイルがchmodsになるという事実も確認しました-o -name "*"(もちろん隠されていないファイルは除外されます)。私の最後の試みは代わりにxargsを使用することでした

find . -name ".*" -o -name "*" | xargs chmod go+w

ついに期待通りに働いた。最初のスニペットで私は何を間違えましたか?

Red Hat Enterprise Linuxサーバーバージョン6.8(サンディエゴ)

GNU bash、バージョン 4.3.42(1)-リリース(x86_64-unknown-linux-gnu)

答え1

解決策は、2つの名前テストを一緒にまとめることです。

これを説明するために、3つの一般的なファイルを含むディレクトリを考えてみましょう。

$ ls -a
.  ..  .hidden1  .hidden2  not_hidden

それでは、元のコマンドを見てみましょう。

$ find . -name ".*" -o -name "*" -exec echo Found {} \;
Found ./not_hidden

隠されていないファイルのみが見つかります。

次に、2つの名前テストをまとめてグループ化するために括弧を追加します。

$ find . \( -name ".*" -o -name "*" \) -exec echo Found {} \;
Found .
Found ./not_hidden
Found ./.hidden1
Found ./.hidden2

すべてのファイルが見つかりました。

解決策は括弧を使用することです。

詳しくは

-name "*"元のコマンドでは、との間に演算子はありません-exec ... \;。したがって、find基本演算子は論理ANDと見なされます。論理ANDは論理OR()よりも密接にバインドされているため、-oコマンドは次のように解釈されます。

find . \( -name ".*" \) -o \( -name "*" -exec echo Found {} \; \)

つまり、最初の条件が一致しないexec場合にのみ実行されます。name

詳細については、次を参照してください。オペレーターに参加man find

そうでなければどうなりますか?-exec

簡単なものを試してみましょう-print

$ find . -name ".*" -o -name "*" -print
./not_hidden

ご覧のとおり、上記の暗黙の論理「and」で-printリンクされています。-name "*"

ただし、ジョブが指定されていない場合は、何が起こるかを検討してください。

$ find . -name ".*" -o -name "*"
.
./not_hidden
./.hidden1
./.hidden2

この時点ですべてのファイルが見つかりました。その理由は、このバージョン-oではただオペレーター。

関連情報