Datei- und Verzeichnisrechte unter Linux sichern

Datei- und Verzeichnisrechte unter Linux sichern

Hallo zusammen,

Die Möglichkeit des sicherns von Datei- und Verzeichnisrechten unter Linux war mir bereits mehrfach extrem hilfreich. Hier zeige ich euch, wie das funktionieren kann.

Schon einmal während der Fehlersuche in einem Unterverzeichnis alles auf 777 gesetzt? Danach hat es vielleicht sogar funktioniert – was bedeutet, dass der Grund eures Fehlers sicher etwas mit Zugriffsrechten im Dateisystem zu tun hat – allerdings sind damit die originalen Datei- und Verzeichnisrechte „futsch“.

Klar kann man sich vorher einen tar-ball ziehen. Geht aber auch geschickter. *daumenhoch*

Der Einzeiler: „Datei- und Verzeichnisrechte unter Linux sichern“

Ich möchte euch heute einen Einzeiler vorstellen, der mir persönlich schon einige Male gute Dienste erwiesen hat:

find ./ -exec sh -c 'echo "chown `stat -c %u:%g \"{}\"` \
\"{}\"; chmod `stat -c %a \"{}\"` \"{}\""' \;

Das Ergebnis ist ziemlich spannend. Der Einzeiler „wirft“ chown und chmod Zeilen (eine Zeile für jede Datei oder Verzeichnis im aktuellen Verzeichnis und abwärts) aus, die direkt ausgeführt werden können um die Berechtigungen wieder zurückzusetzen. Wenn man also die Ausgabe des Befehls in eine Datei umleitet, so erhält man ein bash-Skript, welches die Berechtigungen der ausgelesenen Dateien 1:1 wieder herstellt. *daumenhoch*

Mag dem ein oder anderen vielleicht wie alter Käse vorkommen – nach meiner Erfahrung kennen viele diese Möglichkeit aber leider nicht.

Vom Erklärbären: Wie genau funktioniert nun der Einzeiler „Datei- und Verzeichnisrechte unter Linux sichern“

find ./

Der erste Teil des Einzeilers ist der Befehl find. Dieser listet ohne weitere Parameter alle gefundenen Datei- und Verzeichnisnamen in voller Länge auf. Setzt man wie ich in diesem Beispiel einen Punkt vor den Forward-Slash, so erhält man relative Datei- und Verzeichnisnamen zum aktuellen Verzeichnis bei Befehlsausführung. Diese Liste benötigen wir, um jedes Verzeichnis und jede Datei bei unserer Ausgabe zu berücksichtigen.

Der Befehl find hat einen interessanten Parameter: -exec [Befehl] \;. Dieser weisst dem Befehl find an, pro ausgegebener Zeile einen Befehl auszuführen. Wichtig ist, dass der Befehl mit einem Back-Slash und einem Semikolon abschließt. So weiß find, wo der „exec“ Befehl auch tatsächlich endet. In unserem Fall möchten wir gerne, das eine Shell aufgerufen wird, in der ein weiteres Kommando ausgeführt wird. Um eine Shell aufzurufen und direkt ein Kommando auszuführen (und die Shell wieder schliessen zu lassen), kann man folgenden Befehl verwenden:

sh -c 'echo "Diese Ausgabe kommt aus einer eigenen Shell"'

Seltsam. Wenn der Befehl find schon ein Kommando ausführen kann, warum rufen wir eine Shell auf, die selbst ein Kommando ausführt? Berechtigte Frage. Leider ist die Möglichkeit der Befehlsausführung durch find sehr begrenzt. Find mag z.B. nicht, wenn Ausgaben zu sehr manipuliert – also wie in unserem Fall – erweitert werden. Aus diesem Grund überlassen wir das schön einer Subshell.

Der eigentlich pro durch find gefundenes Verzeichnis oder Datei ausgeführte Befehl lautet dann:

echo "chown `stat -c %u:%g \"{}\"` \"{}\""

Jetzt wird es ein wenig komplizierter. Aber ich versuche mich einzeln „durchzuhangeln“. Zur Vereinfachung habe ich das sich wiederholende Schema im kompletten Befehl gekürzt.

Was auf den ersten Blick klar sein dürfte ist, dass der Befehl echo die fertigen Befehlszeilen ausgibt. Auffällig ist die Verwendung eines weiteren Kommandos namens stat, die Verwendung des schrägen Single-Tick: ` und der Zeichenkombination \"{}\".

Als ersten sollte ich mit der Verwendung des besonderen Single-Tick beginnen. Dieses ` weißt die aktuelle Shell (also die Shell die wir durch find und dessen Parameter -exec haben aufrufen lassen) an, ein Kommando zu substituieren. Soll heißen: Die Ausgabe des Befehles zwischen diesen Single-Ticks wird an die Stelle des auszuführenden Befehls gesetzt.

Vielleicht macht es Sinn, das Beispiel an dieser Stelle weiter zu vereinfachen:

echo "`stat -c %u:%g /etc/profile`"

Die Ausgabe sollte: 0:0 entsprechen. Der Befehl stat gibt mit den Parametern -c %u:%g und anschliessender Verzeichnis- oder Dateiangabe die owner- und group-ID zurück. Da das Kommando substituiert ausgeführt wird, ersetzt es sich selbst in den Parametern des Befehles echo durch seine eigene Ausgabe: echo "0:0"

Jetzt bleibt tatsächlich nur noch das Geheimnis der Zeichenkombination \"{}\", welches irgendetwas mit Verzeichnis- und Dateinamen zu tun haben muss.

Richtig. Aber eigentlich handelt es sich genau genommen nur um die beiden Curly-Brackets {}. Diese weissen das Kommando find vor der Ausführung des -exec Parameters an, an dieser Stelle (wo und wie oft auch immer angegeben) den aktuell gefundenen Verzeichnis oder Dateinamen einzufügen. So kommt der Befehl stat dann auch an seinen benötigten Parameter um die owner- und group-ID auszulesen.

Die doppelten Anführungszeichen sorgen nur dafür, dass bei Leerzeichen in Datei- oder Verzeichnisnamen keine Fehler bei späterer Skriptausführung auftreten.

So, dass war’s wieder. Ich hoffe der Einzeiler „Datei- und Verzeichnisrechte unter Linux sichern“ macht Sinn und ist euch vielleicht ebenso nützlich wie er mir schon oft war. 🙂

Viel Spaß,
swarkn

swarkn

swarkn

Stefans Schwerpunkte liegen im Umfeld von Betriebssystemen, serverbasierten Diensten und im weitesten Sinne in allgemeiner technischer Infrastruktur. Tagsüber mit strategischen IT-Themen beschäftigt, tackert er Nachts doch mal gerne ins schwarze Loch.
swarkn
pinterest
swarkn

Autor: swarkn

Stefans Schwerpunkte liegen im Umfeld von Betriebssystemen, serverbasierten Diensten und im weitesten Sinne in allgemeiner technischer Infrastruktur. Tagsüber mit strategischen IT-Themen beschäftigt, tackert er Nachts doch mal gerne ins schwarze Loch.

Schreib uns einen Kommentar :)