나는 내 개인 디렉토리의 백업을 망쳤습니다 rsync
(아마 NTFS 파일 시스템에서 백업하고 있기 때문일 것입니다). 모든 파일은 여기에 있지만 모든 파일 및 디렉토리 액세스 권한은 777입니다.마법재귀적으로 변경되는 유틸리티:
- 777부터 755까지의 디렉토리.
- 일반 파일은 777부터 644까지입니다. 집에 실행 파일이 많지 않아서 나중에 직접 관리할 수 있습니다.
- 다른 파일(링크, 기타 사항 등)은 변경하지 않고 그대로 둡니다.
쉘에서 수행하는 것은 쉽지만 몇 시간이 걸릴 것입니다...
rsync
보조 질문: NTFS( 또는 기타) 에서 Linux 디렉터리 계층 구조를 올바르게 백업하기 위한 조언 .
답변1
표준 권장 솔루션은 간단합니다.
find . -type d -exec chmod 0755 "{}" \+
find . -type f -exec chmod 0644 "{}" \+
이는 시스템의 최대 명령줄 길이까지 단일 명령에 대한 인수로 가능한 한 많은 파일 이름을 추가합니다. 줄이 이 길이를 초과하면 명령이 여러 번 호출됩니다.
파일당 한 번씩 명령을 호출하려면 다음을 수행하면 됩니다.
find . -type d -exec chmod 0755 "{}" \;
find . -type f -exec chmod 0644 "{}" \;
답변2
chmod -R a=,u+rwX,go+rX $DIR
잘 작동하는 것 같고, 어떻게 보더라도 가장 빠를 가능성이 높습니다.
(나는 으로 확인했는데 strace
, 그것은 단지하나 fchmodat()
파일/디렉토리별 syscall - 644인 파일과 755인 디렉토리의 경우).
비결은 X
에 문서화된 권한 입니다 man chmod
. 이는 x
디렉토리에만 적용되는 것처럼 작동합니다. 이는 여러분이 원했던 바로 그 구별입니다.
무엇인가요~ 아니다문서에는 무작위 순서가 아닌 지정된 순서대로 적용될 것이라는 내 추측이 기록되어 있습니다. 그러나 여러 변형을 사용한 반복 테스트를 통해 실제로 주어진 순서대로 실행된다는 확신이 들었습니다. 이것은 항상 이렇게 작동할 것입니다.
chmod에 대한 BSD 맨페이지를 대충 읽어보면 이것이 Linux에 있다는 것을 언급해야 합니다.~해야 한다거기에서도 일해.
답변3
벤치마킹했어요시타람의 대답,피터 코르데스의 논평,파나티크의 답변, 그리고해리맥의 대답, 하지만이 답변이 가장 빠른 방법입니다.
평균:
- Deltik의 답변* – 7.480초
* 출처:피터 코르데스~을 위한병렬성을 제안 - sitaram의 답변 - 12.962초(최고보다 73.275% 느림)
- Peter Cordes의 의견 – 14.414초(최고보다 92.685% 느림)
- Fanatique의 답변 - 14.570초(최고보다 94.772% 느림)
- harrymc의 업데이트된 답변 – 14.791초(최고보다 97.730% 느림)
- harrymc의 원래 답변 – 1061.926초(최고보다 14096.113% 느림)
전체 통계 요약:
Author N min q1 median q3 max mean stddev
------------------ -- ------- ------- ------- ------- ------- ------- --------
Deltik 10 7.121 7.3585 7.4615 7.558 8.005 7.4804 0.248965
sitaram 10 12.651 12.803 12.943 13.0685 13.586 12.9617 0.276589
Peter Cordes 10 14.096 14.2875 14.375 14.4495 15.101 14.4136 0.269732
Fanatique 10 14.219 14.512 14.5615 14.6525 14.892 14.5697 0.211788
harrymc (updated) 10 14.38 14.677 14.8595 14.9025 15.119 14.791 0.21817
harrymc (original) 1 1061.93 1061.93 1061.93 1061.93 1061.93 1061.93 N/A
벤치마크 형식의 Deltik 명령:
"$(pwd)" 찾기 -type d -print0 | xargs -0 -P4 chmod 755 & \ "$(pwd)" 찾기 -type f -print0 | xargs -0 -P4 chmod 644 & 대기
벤치마크 형식의 sitaram 명령:
chmod -R a=,u+rwX,go+rX "$(pwd)"
벤치마크 형식의 Peter Cordes 명령:
"$(pwd)" 찾기 \( -type d -exec chmod 755 {} + \) \ -o \( -type f -exec chmod 644 {} + \)
Fanatique의 명령(벤치마크 형식):
"$(pwd)" 찾기 -type d -print0 | xargs -0 chmod 755 ; \ "$(pwd)" 찾기 -type f -print0 | xargs -0 chmod 644
harrymc의 업데이트된 명령(벤치마크 형식):
"$(pwd)" 찾기 -type d -exec chmod 755 {} + ; \ "$(pwd)" 찾기 -type f -exec chmod 644 {} +
harrymc의 원래 명령(벤치마크 형식):
"$(pwd)" 찾기 -type d -exec chmod 755 {} \; ; \ "$(pwd)" 찾기 -type f -exec chmod 644 {} \;
chmod
파일 유형당 4개의 병렬 프로세스 덕분에 내 명령이 가장 빨랐습니다 . 이로 인해 여러 CPU 코어가 실행될 수 있었고 chmod
병목 현상이 커널 I/O 스레드나 디스크로 이동했습니다.
sitaram의 명령은 모든 것이 명령 내에서 이루어지기 때문에 준우승이었습니다 chmod
. 이는 다음과 같은 이유로 다른 답변에 비해 오버헤드를 크게 줄입니다.
- 파일은 한 번만 스캔하면 됩니다(
find
두 개가 아닌 한 개를 수행하는 것과 유사함). - 하위 프로세스를 생성할 필요가 없습니다.
그러나 이 명령은 일반 파일과 디렉터리 사이의 실행 가능 비트의 다른 의미와 관련된 트릭에 의존하기 때문에 유연성이 가장 낮습니다.
하나의 명령을 사용하는 Peter Cordes의 설명은 find
디렉토리 항목의 이중 조회를 방지합니다. 파일이 많을수록 이러한 개선 효과는 더욱 커집니다. 여전히 하위 프로세스를 생성하는 오버헤드가 있으므로 -only 솔루션 chmod
보다 속도가 상당히 느립니다 chmod
.
Fanatique의 명령과 harrymc의 업데이트된 명령 사이에서 ( ) find
로 파이프되는 것은 결과 스트림이 비동기적으로 처리되기 때문에 더 빠릅니다. 에 대한 찾기 동작을 일시 중지하는 대신 발견된 결과가 동시 처리를 위해 으로 전송됩니다 . (널바이트 구분자( )는 실행시간에 영향을 미치지 않는 것으로 보입니다.)xargs
find | xargs
find
-exec
xargs
find -print0 | xargs -0
chmod
harrymc의 원래 명령은 각각 순서대로 실행되는 모든 단일 파일 및 폴더에 대한 새 명령의 오버헤드로 인해 너무 느렸습니다 .
테스트 설정에는 1001개의 디렉터리에 1000002개의 일반 파일이 포함되어 있었습니다.
root@demo:~# echo {0..999} | xargs mkdir -p root@demo:~# find -type d -exec bash -c "cd {}; echo {0..999} | xargs touch" \; root@demo:~# 찾기 | 화장실 -l 1001003 root@demo:~# find -type d | 화장실 -l 1001 root@demo:~# find -type f | 화장실 -l 1000002
777
질문의 초기 조건처럼 모든 파일과 폴더에 권한을 갖도록 설정했습니다 .
그런 다음 테스트를 실행하기 전에 777
권한 을 복원할 때마다 명령을 10번 벤치마킹했습니다 .chmod -R 0777 "$(pwd)"
OUTPUT
각 벤치마크 명령의 출력이 포함된 파일을 표현하면서 다음을 사용하여 평균 시간을 계산했습니다 .
bc <<< "scale=3; ($(grep real OUTPUT | grep -Po '(?<=m).*(?=s)' | xargs | sed 's/ /+/g'))/10"
Deltik의 답변 벤치마크 결과
root@demo:~# for i in {0..9} ; chmod -R 0777 "$(pwd)" ; time { "$(pwd)" 찾기 -type d -print0 | xargs -0 -P4 chmod 755 & "$(pwd)" 찾기 -type f -print0 | xargs -0 -P4 chmod 644 & 기다려; } ; 완료 [1] 9791 [2] 9793 [1]- "$(pwd)" 찾기 완료 -d 유형 | xargs -P4 chmod 755 [2]+ "$(pwd)" 찾기 완료 -type f | xargs -P4 chmod 644 실제 0m7.634s 사용자 0m2.536s 시스템 0m23.384s [1] 9906 [2] 9908 [1]- "$(pwd)" 찾기 완료 -d 유형 | xargs -P4 chmod 755 [2]+ "$(pwd)" 찾기 완료 -type f | xargs -P4 chmod 644 실제 0m7.443s 사용자 0m2.636s 시스템 0m23.106s [1] 10021 [2] 10023 [1]- "$(pwd)" 찾기 완료 -d 유형 | xargs -P4 chmod 755 [2]+ "$(pwd)" 찾기 완료 -type f | xargs -P4 chmod 644 실제 0m8.005s 사용자 0m2.672s 시스템 0m24.557s [1] 10136 [2] 10138 [1]- "$(pwd)" 찾기 완료 -d 유형 | xargs -P4 chmod 755 [2]+ "$(pwd)" 찾기 완료 -type f | xargs -P4 chmod 644 실제 0분7.480초 사용자 0m2.541s 시스템 0m23.699s [1] 10251 [2] 10253 [1]- "$(pwd)" 찾기 완료 -d 유형 | xargs -P4 chmod 755 [2]+ "$(pwd)" 찾기 완료 -type f | xargs -P4 chmod 644 실제 0m7.397s 사용자 0m2.558s 시스템 0m23.583s [1] 10366 [2] 10368 [1]- "$(pwd)" 찾기 완료 -d 유형 | xargs -P4 chmod 755 [2]+ "$(pwd)" 찾기 완료 -type f | xargs -P4 chmod 644 실제 0m7.482s 사용자 0m2.601s 시스템 0m23.728s [1] 10481 [2] 10483 [1]- "$(pwd)" 찾기 완료 -d 유형 | xargs -P4 chmod 755 [2]+ "$(pwd)" 찾기 완료 -type f | xargs -P4 chmod 644 실제 0분7.679초 사용자 0m2.749s 시스템 0m23.395s [1] 10596 [2] 10598 [1]- "$(pwd)" 찾기 완료 -d 유형 | xargs -P4 chmod 755 [2]+ "$(pwd)" 찾기 완료 -type f | xargs -P4 chmod 644 실제 0m7.243s 사용자 0m2.583s 시스템 0m23.400s [1] 10729 [2] 10731 [1]- "$(pwd)" 찾기 완료 -d 유형 | xargs -P4 chmod 755 [2]+ "$(pwd)" 찾기 완료 -type f | xargs -P4 chmod 644 실제 0분7.320초 사용자 0m2.640s 시스템 0m23.403s [1] 10844 [2] 10847 [1]- "$(pwd)" 찾기 완료 -d 유형 | xargs -P4 chmod 755 [2]+ "$(pwd)" 찾기 완료 -type f | xargs -P4 chmod 644 실제 0m7.121s 사용자 0m2.490s 시스템 0m22.943s
평균 시간: 7.480초
sitaram의 답변 벤치마크 결과
root@demo:~# for i in {0..9} ; chmod -R 0777 "$(pwd)" ; 시간 chmod -R a=,u+rwX,go+rX "$(pwd)" ; 완료 실제 0분12.860초 사용자 0m0.940s 시스템 0m11.725s 실제 0m13.059s 사용자 0m0.896s 시스템 0m11.937s 실제 0분12.819초 사용자 0m0.945s 시스템 0m11.706s 실제 0m13.078s 사용자 0m0.855s 시스템 0m12.000s 실제 0m12.653s 사용자 0m0.856s 시스템 0m11.667s 실제 0m12.787s 사용자 0m0.820s 시스템 0m11.834s 실제 0m12.651s 사용자 0m0.916s 시스템 0m11.578s 실제 0분13.098초 사용자 0m0.939s 시스템 0m12.004s 실제 0m13.586s 사용자 0m1.024s 시스템 0m12.372s 실제 0m13.026s 사용자 0m0.976s 시스템 0m11.910s
평균 시간: 12.962초
Peter Cordes의 의견에 대한 벤치마크 결과
root@demo:~# for i in {0..9} ; chmod -R 0777 "$(pwd)" ; 시간 찾기 "$(pwd)" \( -type d -exec chmod 755 {} + \) -o \( -type f -exec chmod 644 {} + \) ; 완료 실제 0m14.096s 사용자 0m1.455s 시스템 0m12.456s 실제 0m14.492s 사용자 0m1.398s 시스템 0m12.897s 실제 0m14.309s 사용자 0m1.518s 시스템 0m12.576s 실제 0m14.451s 사용자 0m1.477s 시스템 0m12.776s 실제 0m15.101s 사용자 0m1.554s 시스템 0m13.378s 실제 0m14.223s 사용자 0m1.470s 시스템 0m12.560s 실제 0m14.266s 사용자 0m1.459s 시스템 0m12.609s 실제 0m14.357s 사용자 0m1.415s 시스템 0m12.733s 실제 0m14.393s 사용자 0m1.404s 시스템 0m12.830s 실제 0분14.448초 사용자 0m1.492s 시스템 0m12.717s
평균 시간: 14.414초
Fanatique의 답변 벤치마크 결과
root@demo:~# for i in {0..9} ; chmod -R 0777 "$(pwd)" ; time { "$(pwd)" 찾기 -type d -print0 | xargs -0 chmod 755 ; "$(pwd)" 찾기 -type f -print0 | xargs -0 chmod 644 ; } ; 완료 실제 0m14.561s 사용자 0m1.991s 시스템 0m13.343s 실제 0m14.521s 사용자 0m1.958s 시스템 0m13.352s 실제 0m14.696s 사용자 0m1.967s 시스템 0m13.463s 실제 0m14.562s 사용자 0m1.875s 시스템 0m13.400s 실제 0m14.609s 사용자 0m1.841s 시스템 0m13.533s 실제 0m14.892s 사용자 0m2.050s 시스템 0m13.630s 실제 0m14.291s 사용자 0m1.885s sys 0m13.182s 실제 0m14.843s 사용자 0m2.066s 시스템 0m13.578s 실제 0분 14.219초 사용자 0m1.837s 시스템 0m13.145s 실제 0m14.503s 사용자 0m1.803s 시스템 0m13.419s
평균 시간: 14.570초
harrymc의 업데이트된 답변 벤치마크 결과
root@demo:~# for i in {0..9} ; chmod -R 0777 "$(pwd)" ; 시간 { "$(pwd)" 찾기 -type d -exec chmod 755 {} + ; "$(pwd)" 찾기 -type f -exec chmod 644 {} + ; } ; 완료 실제 0분14.975초 사용자 0m1.728s 시스템 0m13.050s 실제 0분14.710초 사용자 0m1.586s 시스템 0m12.979s 실제 0m14.644s 사용자 0m1.641s 시스템 0m12.872s 실제 0분14.927초 사용자 0m1.706s 시스템 0m13.036s 실제 0m14.867s 사용자 0m1.597s 시스템 0m13.086s 실제 0분 15.119초 사용자 0m1.666s 시스템 0m13.259s 실제 0m14.878s 사용자 0m1.590s 시스템 0m13.098s 실제 0m14.852s 사용자 0m1.681s 시스템 0m13.045s 실제 0분14.380초 사용자 0m1.603s 시스템 0m12.663s 실제 0분14.558초 사용자 0m1.514s 시스템 0m12.899s
평균 시간: 14.791초
harrymc의 원래 답변 벤치마크 결과
이 명령이 너무 느리기 때문에 벤치마크를 한 번만 실행했습니다.
root@demo:~# for i in {0..0} ; chmod -R 0777 "$(pwd)" ; 시간 { "$(pwd)" 찾기 -type d -exec chmod 755 {} \; ; "$(pwd)" 찾기 -type f -exec chmod 644 {} \; ; } ; 완료 실제 17분 41.926초 사용자 12m26.896s 시스템 4m58.332s
걸린 시간: 1061.926초
답변4
디렉토리가 너무 크고 파일이 너무 많으면 @harrymc가 보여준 원래 방식이 실패할 것입니다.
파일이 너무 많으면 다음을 사용하여 find
파이프 해야 합니다 .xargs
chmod
find /base/dir -type d -print0 | xargs -0 chmod 755
find /base/dir -type f -print0 | xargs -0 chmod 644