chown -Rから複数のディレクトリを除外する方法は?

chown -Rから複数のディレクトリを除外する方法は?

Docker の実行時に Synology NAS で問題が発生する権限を修正するために bash エイリアスを作成しています。 /volume1/dockerディレクトリ(Synologyシステムフォルダ@eaDir#recycle

ここで利用可能な次のコマンドのすべてのバージョンを試しましたが、これまで何も機能しませんでした。

sudo find . \( ! -path '*/@eaDir/*' -o ! -path '*/\#recycle/*' \) -exec chown user:group {} +

始点は現在のディレクトリです。その中のすべてのファイルを除外@eaDirします。#recycle助けが必要ですか?

答え1

\( ! -path '*/@eaDir/*' -o ! -path '*/\#recycle/*' \)ロジックが間違っています。パスに含まれていない(例:is)、含まれていない(例:is)ファイルと一致します。除外される唯一のファイルは、パスに以下が含まれるファイルです。/@eaDir/./foo/bar./#recycle/whatever/#recycle/./foo/bar./@eaDir/whatever両方 /@eaDir/そして/#recycle/(例えば./#recycle/@eaDir/whatever)

代わりに、次のようになります。

sudo find . ! '(' -path '*/@eaDir/*' -o -path '*/#recycle/*' ')' \
            -exec chown -h user:group {} +

または:

sudo find . ! -path '*/@eaDir/*' \
            ! -path '*/#recycle/*' \
            -exec chown -h user:group {} +

または:

sudo find . -path '*/@eaDir/*' -o \
            -path '*/#recycle/*' -o \
            -exec chown -h user:group {} +

また、-hファイル形式についてはシンボリックリンク、更新されるのは、ターゲット(一部のシステム内にある場合も#recycleありません@eaDir)ではなく、シンボリックリンクです。

findファイルの検索とファイルの所有権の実行と変更の間に競合ウィンドウがあるため、このアプローチはまだ安全ではありません。chownこの間、システムユーザーはディレクトリコンポーネントをsystem / sensitiveディレクトリを指すシンボリックリンクに置き換えることができます。システムがサポートしている場合は、これが-execdir役に立ちます(ただし、ディレクトリごとに少なくとも1回、複数回実行する必要があるため、-exec時間がかかります)。chown

また、ディレクトリにあるファイルでない場合はディレクトリ自体を chown し@eaDir、使用されない場合はディレクトリにあるすべてのファイルを探します。#recycleexecchown

より良い方法は次のとおりです。

find . '(' -name @eaDir -o -name '#recycle' ')' -prune -o \
       -exec chown -h user:group {} +

chownすでに所有しているファイルで実行されないようにすることもできますuser:group

find . '(' -name @eaDir -o -name '#recycle' ')' -prune -o \
       -user user -group group -o \
       -exec chown -h user:group {} +

いつものように、-a2つの述語の間で省略すると、aが暗黙的に(-user user -group groupisの略語-user user -a -group group)、多くの言語と同様に、aが:is-aよりも優先されます。したがって、非常に明確にしたい場合は、上記の内容を次のように作成できます。-oA -a B -o C -a D( A -a B ) -o (C -a D)

find .                                          \
  '('                                           \
    '(' -name @eaDir -o -name '#recycle' ')' -a \
    -prune                                      \
  ')' -o '('                                    \
    -user user -a -group group                  \
  ')' -o                                        \
  -exec chown -h user:group {} +

関連情報