Linux ext4 stellt Datei- und Verzeichniszugriffsrechte nach fehlerhafter Sicherung/Wiederherstellung wieder her

Linux ext4 stellt Datei- und Verzeichniszugriffsrechte nach fehlerhafter Sicherung/Wiederherstellung wieder her

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 rsyncoder 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 $DIRscheint 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 Xin dokumentierten Berechtigung, man chmoddie so wirkt, als ob sie xnur 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 chmodProzesse 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 chmodBefehls 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 findstatt 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 chmodProzessen, weshalb es um einiges langsamer ist als die chmod-only-Lösung.

Zwischen Fanatiques Befehl und harrymcs aktualisiertem Befehl war finddie Weiterleitung in xargs( find | xargs) schneller, da der Ergebnisstrom asynchron verarbeitet wird. Anstatt finddas Suchverhalten für anzuhalten , werden die gefundenen Ergebnisse zur gleichzeitigen Verarbeitung -execan 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 chmodfü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 777Berechtigungen festgelegt, die den Anfangsbedingungen der Frage entsprechen.

Anschließend habe ich die Befehle zehnmal getestet und jedes Mal die Berechtigungen vor 777dem chmod -R 0777 "$(pwd)"Ausführen des Tests wiederhergestellt.

Indem OUTPUTich 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 findFolgendes xargsweiterleiten chmod:

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

verwandte Informationen