수천 개의 파일에 대한 chmod 재귀 권한


16

이것은 'chmoding'에 대한 일반적인 질문입니다.

이 스크립트는 어느 시점에서 몇 십만 개의 파일이있는 폴더에서 재귀 적으로 권한을 변경해야하는 스크립트입니다. 매일 해당 폴더에 새 파일이 추가되지만 이미 존재하는 파일은 이미 권한이 설정되어 있으며 변경되지 않습니다.

내 질문은 ... 전화 할 때

chmod 775. -아르 자형

올바른 권한이 설정되어있는 파일 또는 올바른 권한이없는 새 파일에 대해서만 권한을 설정하려고합니까?

'새'파일이 단지 수천 개인데도 권한을 상당히 빨리 수행해야하지만 스크립트에서이 명령을 수행하는 데 항상 오랜 시간이 걸리는 것 같습니다.

chmod의 맨 페이지를 보았지만이 경우에는 언급이없는 것 같습니다.

chmod가 사전에 권한을 확인하지 않으면 'find'와 'chmod'의 결합을 검토해야합니까?


3
권한을 확인하고 올바른 값으로 직접 설정하는 것보다 권한이 올바르지 않은 경우 변경하는 것이 실제로 느린 지 궁금합니다.
lgeorget

1
누군가 이것을 우연히 발견하고 find + chmod 명령을 원하면 여기에 find가 있습니다. ! -perm 775 -print0 | xargs -0 -I {} chmod 775 {}
Titi Dumi

@lgeorget, 그래서 find | chmod를 사용하는 것이 느리다고 말하는 것입니까? 모든 것을 chmod하는 것보다. (죄송합니다, 귀하의 의견을 이해하지 못했습니다). 건배
티티 두미

겸손한 견해로는 두 프로세스를 시작하고 첫 번째 프로세스의 출력을 두 번째 프로세스로 리디렉션해야하기 때문에 속도가 느릴 수 있지만 확실하지 않습니다. 사용 권한을 설정하는 데 걸리는 시간에 따라 다르며, inode에서 수정하는 데 3 바이트에 불과하므로 중요하지 않을 수 있습니다.
lgeorget

1
@depquid 여기서 주요 성능 문제는 디스크 캐시로 데이터를 읽는 것입니다. 첫 번째 실행 후 모든 메모리가 부족하지 않은 한 모든 것이 디스크 캐시에 있으므로 실제 상황에서 병목 현상이 아닌 무언가의 성능을 테스트합니다.
Hauke ​​Laging

답변:


9

chmod이미 원하는 것으로 설정된 파일의 권한을 변경하거나 변경하지 않을 수 있지만, 그렇지 않은 경우 여전히 현재 권한이 무엇인지 확인하기 위해 파일을 확인해야합니다 [0]. 수십만 개의 파일이 있기 때문에 어느 쪽이든 중요하지 않다고 생각합니다. stat모든 파일 을 작성하는 도구가 시간을 소비 할 가능성이 높습니다 .

당신은 사용해 볼 수 있습니다 find마지막으로 실행 또는 필요가 있음을 파일보다 최신 파일 중 하나를 확인하기 위해 chmod실행하는,하지만 난 당신이 더 속도 향상을 얻을 수있을 거라 생각하지 않습니다.

스크립트에서 가능하면 새 파일을 "보류"영역으로 먼저 별도의 디렉토리에 넣을 수 있습니다. 그런 다음 chmod새 디렉토리 만있는 디렉토리를 mv나머지와 함께 사용할 수 있습니다. 그것은 훨씬 빠르지 만 불행히도 모든 응용 프로그램에서 작동하지는 않습니다.

[0] 변경이 필요없는 파일의 권한을 설정하려고해도 기본 파일 시스템은 필요하지 않기 때문에 요청과 관련이 없을 것입니다.


고마워 나는 찾기를 시도합니다 | chmod 버전을 사용하여 더 빠른지 확인하십시오. 그렇지 않으면 제안한대로 'holding'폴더를 구현하도록 스크립트를 수정하려고 시도합니다.
티티 두미

속도 향상을 얻지 못하는 이유는 ctime과 액세스 권한 모두에 대해 inode를 읽어야하기 때문입니다.
Hauke ​​Laging

10

찾기 / chmod 최적화

모두 findchmod읽을 필요

  1. 모든 디렉토리 항목
  2. 이 모든 엔트리의 inode

디스크 헤드가 디렉토리와 inode간에 이동하지 않기 때문에 먼저 모든 항목을 읽은 다음 모든 inode (회전하는 디스크의)를 읽음으로써 성능이 향상 될 수 있습니다. 로 chmod 이다 바보 (다른 답변 중 하나가 설명 하듯이)가 통해 호출해야 find만. 그러나 그때조차도 첫 번째 쓰기가 시작되기 전에 모든 inode를 읽는 데 도움이 될 수 있습니다 (디스크 캐시에 충분한 여유 RAM이 있다고 가정). 나는 이것을 제안한다 :

find . -printf "" # reading the file names only
find . ! -perm 775 -printf "" # reading all the inodes (file names are cached)
find . ! -perm 775 -exec chmod 775 + # writing to the cache without reading from disk

좋은 해결책 : ACL

좋은 해결책은 완전히 다를 수 있습니다. 파일이이 디렉토리에 작성되고 다른 곳으로 이동되지 않은 경우 ACL은 즉시 작업을 수행 할 수 있습니다. 부모 디렉토리에서 기본 ACL을 설정하기 만하면됩니다.

파일 시스템 최적화를 통해 추가 개선이 이루어질 수 있습니다. ext3 / ext4 인 경우 e2fsck -D때때로 실행될 수 있습니다 . 이 디렉토리를 별도의 볼륨에 두는 것이 도움이 될 수 있습니다. 다른 파일 시스템 또는 파일 시스템 설정 (예 : 다른 inode 크기)을 시도 할 수 있습니다.


NFSv4 마운트에서 작업하지 않는 한 ACL이 좋습니다.
ostrokach

find솔루션에 대한, 내 시간을 두 배로 chmod고정 표시기 컨테이너 내부에 보내고.
Nathan ReinstateMonica Arthur

8

Ubuntu 12.10 chmodGNU coreutils 패키지 를 사용한다고 가정합니다 .

chmod 775 . -Rfchmodat권한 변경이 필요한지 여부에 관계없이 찾은 각 파일에 대해 시스템 호출을 실행합니다 . 코드를 검사하고 strace chmod 775 . -R(아래 스 니펫)을 사용 하여 실제 동작을 나열 하여이를 확인했습니다 .

newfstatat(4, "d", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat(4, "d", 0775)                  = 0
newfstatat(4, "c", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat(4, "c", 0775)                  = 0
newfstatat(4, "a", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat(4, "a", 0775)                  = 0
newfstatat(4, "b", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat(4, "b", 0775)                  = 0

fchmodat각 파일 에서 실행하는 데는 몇 가지 단점이 있습니다

  • 많은 수의 파일이 변경되면 추가 시스템 호출이 중요해질 수 있습니다. find/ xargs/ chmod다른 사람에 의해 한 방법은 가능성 만 변경 필요 파일을 변경하여 더 빨리 될 것입니다.
  • 호출 fchmodat은 각 파일의 파일 상태 수정 (ctime)을 변경합니다. 이로 인해 매번 모든 파일 / 노드가 변경되고 디스크 쓰기가 과도하게 발생할 수 있습니다. 마운트 옵션을 사용하여 이러한 초과 쓰기를 중지 할 수 있습니다.

간단한 실험은 직선에 대한 ctime 변화를 보여줍니다 chmod

auser@duncow:/tmp/blah.test$ ls -lc
total 0
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 a
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 b
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 c
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 d
auser@duncow:/tmp/blah.test$ chmod 775 . -R
auser@duncow:/tmp/blah.test$ ls -lc
total 0
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 a
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 b
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 c
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 d

그러나 이것은 몇 분 후에 find/ xargs/ 변경되지 않습니다chmod

auser@duncow:/tmp/blah.test$ date
Tue Jun 18 18:27:27 BST 2013
auser@duncow:/tmp/blah.test$ find . ! -perm 775 -print0 | xargs -0 -I {} chmod 775 {}
auser@duncow:/tmp/blah.test$ ls -lc
total 0
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 a
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 b
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 c
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 d

찾기는 물건 선택을보다 잘 제어 할 수 있기 때문에 항상 find/ xargs/ chmod버전 을 사용하는 경향이 있습니다 .


1

[source] (1)은 chmod(1)항상 모드 설정을 시도한 다음 [fstatat (2)] (2)로 다시 확인합니다.

파일은 [fts (3)] (3)을 통해 처리되며, 데이터 트리를 작성하기 전에 먼저 통과 된 모든 파일 시스템 오브젝트를 '통계'해야합니다.

Unixlore의 특징은 [좋은 기사] (4) / 접근 방식 chmod(1)에 따라 시간이 정해진 다 .findxargs

다음은 명령 행이 원래 질문에 맞게 조정 된 것입니다.

find . -print0 | xargs -0 chmod 775

두 가지 이유 :

  1. 파일 시스템 탐색은 두 프로세스 사이의 파이프를 통해 파일의 작업과 분리되며 다른 코어에서 실행될 수도 있습니다.

    1. fts(3)xargs(1)디렉토리 트리가 '평평 해지 기 ' 때문에 작업이 최소화 됩니다.

따라서 그렇습니다 : find/ 를 사용해야합니다 xargs. 간단한 해결책.

다른 옵션:

  • [umask] (5)와 새 파일을 작성하는 프로세스의 소스 코드로 재생하십시오.

  • Linux를 사용하는 경우 시스템에서 inotify커널 서브 시스템을 활성화했을 가능성이 있습니다 . 이 경우 [inotifywait (1)] (6)을 통해 효율적인 솔루션을 스크립팅 할 수 있습니다.


참고 사항 : 파일에 대한 실행 권한을 원하지 않는 한 다음과 같이 호출을 수정하는 것이 좋습니다.

find . -type f -print0 | xargs -0 chmod 664
find . -type d -print0 | xargs -0 chmod 775

편집자 주 : 게시물에 두 개 이상의 링크를 추가하거나 다른 게시물에 댓글을 달 수 없습니다. 나는 URL을 여기에두고 평판이 좋은 열린 사용자가 텍스트에 다시 넣고이 단락을 삭제하기를 바랍니다.


디스크 캐시 프라이밍에 대한 의견find . -printf "":

이는 다음 chmod작업 의 실행 속도를 높일 수 있지만 사용 가능한 메모리 및 i / o로드에 따라 다릅니다. 따라서 작동하거나 작동하지 않을 수 있습니다. 순회 ( find) 및 chmod작업 분리가 이미 캐싱을 제공하므로 캐시 프라이밍이 불필요한 것일 수 있습니다.

  1. https + lingrok.org / xref / coreutils / src / chmod.c # process_file
  2. https + linux.die.net / man / 2 / fstatat
  3. https + linux.die.net / man / 3 / fts
  4. http + www.unixlore.net / articles / speeding-up-bulk-file-operations.html
  5. https + ko.wikipedia.org / wiki / Umask
  6. https + linux.die.net / man / 1 / inotifywait

0

파일을 작성하는 프로세스를 0775 모드로 작성하도록 변경 했습니까? 환경에서 umask 값을 살펴보십시오. 0002가 도움이 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.