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사용 하면 도움이 될 것입니다(그러나 디렉터리당 적어도 한 번씩 여러 번 실행해야 하므로 -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 {} +

항상 그렇듯이 -a두 술어 사이에서 생략되면 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 {} +

관련 정보