잘못된 백업/복원 후 Linux ext4 복원 파일 및 디렉터리 액세스 권한

잘못된 백업/복원 후 Linux ext4 복원 파일 및 디렉터리 액세스 권한

나는 내 개인 디렉토리의 백업을 망쳤습니다 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로 파이프되는 것은 결과 스트림이 비동기적으로 처리되기 때문에 더 빠릅니다. 에 대한 찾기 동작을 일시 중지하는 대신 발견된 결과가 동시 처리를 위해 으로 전송됩니다 . (널바이트 구분자( )는 실행시간에 영향을 미치지 않는 것으로 보입니다.)xargsfind | xargsfind-execxargs
find -print0 | xargs -0

chmodharrymc의 원래 명령은 각각 순서대로 실행되는 모든 단일 파일 및 폴더에 대한 새 명령의 오버헤드로 인해 너무 느렸습니다 .


테스트 설정에는 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파이프 해야 합니다 .xargschmod

find /base/dir -type d -print0 | xargs -0 chmod 755 
find /base/dir -type f -print0 | xargs -0 chmod 644

관련 정보