chmod go+w
隠しファイルを含む特定のフォルダで再帰的に実行したかったので、まず試してみました
find . -name ".*" -o -name "*" -exec chmod go+w {} \;
しかし、隠しファイルには影響がないことが分かりました。確認するために、
find . -name ".*" -o -name "*"
隠しファイルがリストされました。また、その部分を除外すると隠しファイルがchmodされることに気づきました-o -name "*"
(もちろん隠しファイル以外も除外されます)。最後の試みは、代わりにxargsを使用することでした。
find . -name ".*" -o -name "*" | xargs chmod go+w
最終的に期待どおりに動作しました。最初のスニペットで何が間違っているのでしょうか?
Red Hat Enterprise Linux Server リリース 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
はデフォルトの演算子である論理積を想定します。論理積は論理和 ( -o
) よりも結合が強いため、コマンドは次のように解釈されます。
find . \( -name ".*" \) -o \( -name "*" -exec echo Found {} \; \)
これは、exec
最初のname
条件が一致しなかった場合にのみ実行されることを意味します。
詳細については、オペレーターのセクションman find
。
なしで何が起こるか-exec
簡単なものを使ってみましょう-print
:
$ find . -name ".*" -o -name "*" -print
./not_hidden
ご覧のとおり、上記のように暗黙の論理積で-print
バインドされています。-name "*"
しかし、アクションを指定しない場合に何が起こるか考えてみましょう。
$ find . -name ".*" -o -name "*"
.
./not_hidden
./.hidden1
./.hidden2
ここで、すべてのファイルが見つかりました。その理由は、このバージョンでは-o
、のみオペレーター。