Ich habe das Backup meines persönlichen Verzeichnisses irgendwie vermasselt rsync
(vielleicht weil ich es auf einem NTFS-Dateisystem sichere): Alle Dateien sind hier, aber alle Dateien und Verzeichnisse haben Zugriffsrechte von 777. Ich habe mich gefragt, ob es eineMagieDienstprogramm, das rekursiv ändern würde:
- die Verzeichnisse von 777 bis 755.
- die regulären Dateien von 777 bis 644. Ich habe nicht viele ausführbare Dateien zu Hause, daher kann ich das später manuell verwalten.
- Lassen Sie andere Dateien (Links, sonstiges?) unverändert.
Dies in der Shell zu tun ist einfach, wird aber Stunden dauern ...
Zusatzfrage: Irgendwelche Ratschläge zum ordnungsgemäßen Sichern einer Linux-Verzeichnishierarchie auf NTFS (mit rsync
oder anders).
Antwort1
Die empfohlene Standardlösung ist unkompliziert:
find . -type d -exec chmod 0755 "{}" \+
find . -type f -exec chmod 0644 "{}" \+
Dadurch werden so viele Dateinamen wie möglich als Argumente an einen einzelnen Befehl angehängt, bis zur maximalen Befehlszeilenlänge des Systems. Wenn die Zeile diese Länge überschreitet, wird der Befehl mehrmals aufgerufen.
Wenn Sie den Befehl einmal pro Datei aufrufen möchten, können Sie stattdessen Folgendes tun:
find . -type d -exec chmod 0755 "{}" \;
find . -type f -exec chmod 0644 "{}" \;
Antwort2
chmod -R a=,u+rwX,go+rX $DIR
scheint gut zu funktionieren und ist höchstwahrscheinlich die schnellste, wie auch immer man es betrachtet.
(Ich habe nachgeprüft strace
, und es macht nureins fchmodat()
Systemaufruf pro Datei/Verzeichnis – für Dateien mit 644 und für Verzeichnisse mit 755).
Der Trick besteht in der X
in dokumentierten Berechtigung, man chmod
die so wirkt, als ob sie x
nur für Verzeichnisse gilt – genau die Unterscheidung, die Sie wollten.
Was istnichtIch gehe davon aus, dass sie, soweit dokumentiert, in der angegebenen Reihenfolge und nicht in einer zufälligen Reihenfolge ausgeführt werden. Wiederholte Tests mit mehreren Varianten haben mich jedoch davon überzeugt, dass sie tatsächlich in der angegebenen Reihenfolge ausgeführt werden. Daher bin ich ziemlich sicher, dass dies immer so funktionieren wird.
Ich sollte erwähnen, dass dies unter Linux geschieht, obwohl ein flüchtiger Blick auf die BSD-Manpage für chmod darauf schließen lässt, dass essollenarbeite auch dort.
Antwort3
ich habe Benchmarking durchgeführtSitarams Antwort,Kommentar von Peter Cordes,Fanatiques Antwort, UndAntwort von harrymc, Aberdiese Antwort ist der schnellste Weg.
Durchschnitte:
- Deltiks Antwort* – 7,480 Sekunden
* Kredit anPeter CordesfürParallelität nahelegen - Sitarams Antwort – 12,962 Sekunden (73,275 % langsamer als der Durchschnitt)
- Kommentar von Peter Cordes – 14,414 Sekunden (92,685 % langsamer als der Bestwert)
- Fanatiques Antwort – 14,570 Sekunden (94,772 % langsamer als der Bestwert)
- harrymcs aktualisierte Antwort – 14,791 Sekunden (97,730 % langsamer als die beste)
- harrymcs ursprüngliche Antwort – 1061,926 Sekunden (14096,113 % langsamer als die beste)
Vollständige statistische Zusammenfassung:
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
Deltiks Befehl im Benchmarkformat:
finde "$(pwd)" -type d -print0 | xargs -0 -P4 chmod 755 & \ finde "$(pwd)" -type f -print0 | xargs -0 -P4 chmod 644 und warte
Sitarams Befehl im Benchmarkformat:
chmod -R a=,u+rwX,go+rX "$(pwd)"
Der Befehl von Peter Cordes im Benchmarkformat:
finde "$(pwd)" \( -type d -exec chmod 755 {} + \) \ -o \( -type f -exec chmod 644 {} + \)
Fanatiques Befehl im Benchmarkformat:
suche "$(pwd)" -type d -print0 | xargs -0 chmod 755 ; \ finde "$(pwd)" -type f -print0 | xargs -0 chmod 644
Aktualisierter Befehl von harrymc im Benchmarkformat:
finde "$(pwd)" -type d -exec chmod 755 {} + ; \ finde "$(pwd)" -type f -exec chmod 644 {} +
Originalbefehl von harrymc im Benchmarkformat:
finde "$(pwd)" -type d -exec chmod 755 {} \; ; \ finde "$(pwd)" -type f -exec chmod 644 {} \;
Mein Befehl war dank der vier parallelen chmod
Prozesse pro Dateityp der schnellste. Dadurch konnten mehrere CPU-Kerne ausgeführt werden chmod
, wodurch der Engpass in Richtung der Kernel-E/A-Threads oder der Festplatte verschoben wurde.
Sitarams Befehl war der Zweitplatzierte, da alles innerhalb des chmod
Befehls erledigt wird. Dies reduziert den Aufwand im Vergleich zu den anderen Antworten erheblich, weil:
- Die Dateien müssen nur einmal gescannt werden (ähnlich wie bei einer
find
statt zwei Scans) und - Es müssen keine untergeordneten Prozesse erstellt werden.
Dieser Befehl ist jedoch der am wenigsten flexible, da er auf einem Trick beruht, der mit der unterschiedlichen Bedeutung des ausführbaren Bits zwischen normalen Dateien und Verzeichnissen zusammenhängt.
Der Kommentar von Peter Cordes, der einen Befehl verwendet find
, verhindert doppelte Nachschlagevorgänge in Verzeichniseinträgen. Je mehr Dateien vorhanden sind, desto wesentlicher ist diese Verbesserung. Es besteht immer noch der Overhead der Erstellung von untergeordneten chmod
Prozessen, weshalb es um einiges langsamer ist als die chmod
-only-Lösung.
Zwischen Fanatiques Befehl und harrymcs aktualisiertem Befehl war find
die Weiterleitung in xargs
( find | xargs
) schneller, da der Ergebnisstrom asynchron verarbeitet wird. Anstatt find
das Suchverhalten für anzuhalten , werden die gefundenen Ergebnisse zur gleichzeitigen Verarbeitung
-exec
an gesendet . (Das Nullbyte-Trennzeichen ( ) schien die Laufzeit nicht zu beeinflussen.)xargs
find -print0 | xargs -0
Der ursprüngliche Befehl von harrymc war zu langsam, da chmod
für jede einzelne Datei und jeden einzelnen Ordner ein neuer Befehl erforderlich war, der jeweils nacheinander ausgeführt wurde.
Im Test-Setup waren 1000002 reguläre Dateien in 1001 Verzeichnissen enthalten:
root@demo:~# echo {0..999} | xargs mkdir -p root@demo:~# find -type d -exec bash -c "cd {}; echo {0..999} | xargs touch" \; root@demo:~# finden | wc -l 1001003 root@demo:~# find -type d | wc -l 1001 root@demo:~# find -type f | wc -l 1000002
Ich habe für alle Dateien und Ordner die entsprechenden 777
Berechtigungen festgelegt, die den Anfangsbedingungen der Frage entsprechen.
Anschließend habe ich die Befehle zehnmal getestet und jedes Mal die Berechtigungen vor 777
dem chmod -R 0777 "$(pwd)"
Ausführen des Tests wiederhergestellt.
Indem OUTPUT
ich eine Datei darstelle, die die Ausgabe jedes Benchmark-Befehls enthält, habe ich die durchschnittliche Zeit wie folgt berechnet:
bc <<< "scale=3; ($(grep real OUTPUT | grep -Po '(?<=m).*(?=s)' | xargs | sed 's/ /+/g'))/10"
Ergebnisse des Benchmarks von Deltiks Antwort
root@demo:~# für i in {0..9}; mache chmod -R 0777 "$(pwd)"; Zeit { finde "$(pwd)" -type d -print0 | xargs -0 -P4 chmod 755 & finde "$(pwd)" -type f -print0 | xargs -0 -P4 chmod 644 & warte; }; fertig [1] 9791 [2] 9793 [1]- Fertig find "$(pwd)" -type d | xargs -P4 chmod 755 [2]+ Fertig find "$(pwd)" -type f | xargs -P4 chmod 644 real 0m7.634s Benutzer 0m2.536s sys 0m23.384s [1] 9906 [2] 9908 [1]- Fertig find "$(pwd)" -type d | xargs -P4 chmod 755 [2]+ Fertig find "$(pwd)" -type f | xargs -P4 chmod 644 real 0m7.443s Benutzer 0m2.636s sys 0m23.106s [1] 10021 [2] 10023 [1]- Fertig find "$(pwd)" -type d | xargs -P4 chmod 755 [2]+ Fertig find "$(pwd)" -type f | xargs -P4 chmod 644 real 0m8.005s Benutzer 0m2.672s sys 0m24.557s [1] 10136 [2] 10138 [1]- Fertig find "$(pwd)" -type d | xargs -P4 chmod 755 [2]+ Fertig find "$(pwd)" -type f | xargs -P4 chmod 644 real 0m7.480s Benutzer 0m2.541s sys 0m23.699s [1] 10251 [2] 10253 [1]- Fertig find "$(pwd)" -type d | xargs -P4 chmod 755 [2]+ Fertig find "$(pwd)" -type f | xargs -P4 chmod 644 real 0m7.397s Benutzer 0m2.558s sys 0m23.583s [1] 10366 [2] 10368 [1]- Fertig find "$(pwd)" -type d | xargs -P4 chmod 755 [2]+ Fertig find "$(pwd)" -type f | xargs -P4 chmod 644 echt 0m7.482s Benutzer 0m2.601s System 0 m23,728 s [1] 10481 [2] 10483 [1]- Fertig find "$(pwd)" -type d | xargs -P4 chmod 755 [2]+ Fertig find "$(pwd)" -type f | xargs -P4 chmod 644 real 0m7.679s Benutzer 0m2.749s sys 0m23.395s [1] 10596 [2] 10598 [1]- Fertig find "$(pwd)" -type d | xargs -P4 chmod 755 [2]+ Fertig find "$(pwd)" -type f | xargs -P4 chmod 644 echt 0m7.243s Benutzer 0m2.583s System 0 m23,400 s [1] 10729 [2] 10731 [1]- Fertig find "$(pwd)" -type d | xargs -P4 chmod 755 [2]+ Fertig find "$(pwd)" -type f | xargs -P4 chmod 644 real 0m7.320s Benutzer 0m2.640s sys 0m23.403s [1] 10844 [2] 10847 [1]- Fertig find "$(pwd)" -type d | xargs -P4 chmod 755 [2]+ Fertig find "$(pwd)" -type f | xargs -P4 chmod 644 real 0m7.121s Benutzer 0m2.490s sys 0m22.943s
Durchschnittliche Zeit: 7,480 Sekunden
Ergebnisse des Benchmarks von Sitarams Antwort
root@demo:~# für i in {0..9}; führe chmod -R 0777 "$(pwd)" aus; Zeit chmod -R a=,u+rwX,go+rX "$(pwd)"; fertig real 0m12.860s Benutzer 0m0.940s System 0 m11,725 s real 0m13.059s Benutzer 0m0.896s System 0 m11,937 s real 0m12.819s Benutzer 0m0.945s sys 0m11.706s real 0m13.078s Benutzer 0m0.855s System 0 m12.000 s real 0m12.653s Benutzer 0m0.856s sys 0m11.667s real 0m12.787s Benutzer 0m0.820s System 0 m11,834 s real 0m12.651s Benutzer 0m0.916s System 0 m11,578 s real 0m13.098s Benutzer 0m0.939s System 0m12.004s real 0m13.586s Benutzer 0m1.024s sys 0m12.372s real 0m13.026s Benutzer 0m0.976s sys 0m11.910s
Durchschnittliche Zeit: 12,962 Sekunden
Ergebnisse des Benchmarks zum Kommentar von Peter Cordes
root@demo:~# für i in {0..9}; führe chmod -R 0777 "$(pwd)" aus; Zeit finde "$(pwd)" \( -type d -exec chmod 755 {} + \) -o \( -type f -exec chmod 644 {} + \); fertig real 0m14.096s Benutzer 0m1.455s sys 0m12.456s echt 0m14.492s Benutzer 0m1.398s System 0 m12,897 s real 0m14.309s Benutzer 0m1.518s sys 0m12.576s real 0m14.451s Benutzer 0m1.477s sys 0m12.776s real 0m15.101s Benutzer 0m1.554s sys 0m13.378s echt 0m14.223s Benutzer 0m1.470s System 0 m12,560 s echt 0m14.266s Benutzer 0m1.459s sys 0m12.609s real 0m14.357s Benutzer 0m1.415s sys 0m12.733s echt 0m14.393s Benutzer 0m1.404s System 0 m12,830 s real 0m14.448s Benutzer 0m1.492s System 0 m12,717 s
Durchschnittliche Zeit: 14,414 Sekunden
Ergebnisse des Benchmarks der Antwort von Fanatique
root@demo:~# für i in {0..9}; mache chmod -R 0777 "$(pwd)"; Zeit { finde "$(pwd)" -type d -print0 | xargs -0 chmod 755; finde "$(pwd)" -type f -print0 | xargs -0 chmod 644; }; fertig real 0m14.561s Benutzer 0m1.991s sys 0m13.343s real 0m14.521s Benutzer 0m1.958s sys 0m13.352s real 0m14.696s Benutzer 0m1.967s sys 0m13.463s echt 0m14.562s Benutzer 0m1.875s System 0 m13,400 s real 0m14.609s Benutzer 0m1.841s sys 0m13.533s echt 0m14.892s Benutzer 0m2.050s System 0 m13,630 s echt 0m14.291s Benutzer 0m1.885s System 0 m13,182 s echt 0m14.843s Benutzer 0m2.066s System 0 m13,578 s real 0m14.219s Benutzer 0m1.837s sys 0m13.145s real 0m14.503s Benutzer 0m1.803s sys 0m13.419s
Durchschnittliche Zeit: 14,570 Sekunden
Ergebnisse des Benchmarks der aktualisierten Antwort von harrymc
root@demo:~# für i in {0..9}; mache chmod -R 0777 "$(pwd)"; Zeit { finde "$(pwd)" -type d -exec chmod 755 {} +; finde "$(pwd)" -type f -exec chmod 644 {} +; }; fertig real 0m14.975s Benutzer 0m1.728s System 0 m13,050 s real 0m14.710s Benutzer 0m1.586s System 0 m12,979 s real 0m14.644s Benutzer 0m1.641s System 0 m12,872 s real 0m14.927s Benutzer 0m1.706s sys 0m13.036s real 0m14.867s Benutzer 0m1.597s sys 0m13.086s real 0m15.119s Benutzer 0m1.666s sys 0m13.259s real 0m14.878s Benutzer 0m1.590s System 0 m13,098 s echt 0m14.852s Benutzer 0m1.681s System 0 m13,045 s real 0m14.380s Benutzer 0m1.603s sys 0m12.663s real 0m14.558s Benutzer 0m1.514s System 0 m12,899 s
Durchschnittliche Zeit: 14,791 Sekunden
Ergebnisse des Benchmarks der ursprünglichen Antwort von harrymc
Aufgrund der Langsamkeit dieses Befehls habe ich den Benchmark nur einmal ausgeführt.
root@demo:~# für i in {0..0}; mache chmod -R 0777 "$(pwd)"; Zeit { finde "$(pwd)" -type d -exec chmod 755 {} \;; finde "$(pwd)" -type f -exec chmod 644 {} \;; }; fertig real 17m41.926s Benutzer 12m26.896s System 4 Min. 58,332 Sek.
Dauer: 1061,926 Sekunden
Antwort4
Wenn die Verzeichnisse viel zu groß sind und viel zu viele Dateien enthalten, schlägt die ursprüngliche Methode, die @harrymc Ihnen gezeigt hat, fehl.
Wenn Sie zu viele Dateien haben, müssen Sie find
Folgendes xargs
weiterleiten chmod
:
find /base/dir -type d -print0 | xargs -0 chmod 755
find /base/dir -type f -print0 | xargs -0 chmod 644