find: Hardlinks zu Dateien finden

Wie in meinem Blog-Beitrag fdupes- Duplikate finden beschrieben, kann man doppelte Dateien auch mit Hardlinks zusammenführen.
Aber wie findet man solche „verlinkten“ Dateien wieder?
Mit dem Befehl find

Zuerst aber nochmal eine kleine, einfach gehaltene Erklärung zu Hardlinks.
Hardlinks sind nicht zusätzliche Links auf eine Datei; es sind die Links (oder beser Verweise) zu einer Datei.
Jede Datei hat minestens einen Hardlink.
Wird eine Datei erzeugt, wird diese auf dem Dateisystem abgelegt und erhält zur eindeutigen Identifikation eine Nummer – die Inode (das ist etwa so, wie eine Seriennummer).
Zusätzlich bekommt die Datei noch einen Verweis, in welchem Verzeichnis sie „erscheinen“ soll – ihren ersten Hardlink.
Löscht man eine Datei aus einem Verzeichnis, so wird der Hardlink, also der Verweis dieser Datei zu diesem Verzeichnis, gelöscht. Besitzt die Datei keine weiteren Hardlinks, wird sie von Dateisystem verworfen.

Jetzt zur Praxis.
Ber Befehl find beinhaltet u. a. den Parameter -links mit dem man nach der Zahl der Hardlinks einer Datei suchen kann.
Die Eingabe von
find / -links 1
würde alle Dateien ab dem Wurzelverzeichnis (/) anzeigen, welche nur einen Hardlink besitzen.
Möchte man Dateien finden, welche mehr als einen Hardlinks besitzen, nutzt man
find / -links +1
Mehr als zwei Hardlinks würden mit
find / -links +2
angezeigt usw.
Find findet hier nicht nur Dateien, sondern auch Verzeichnisse. Womit wir bei einer weiteren Besonderheit angelangt sind, welche es zu beachten gilt.
Unter Linux-Dateisytemen gibt es keine Verzeichnisse und Dateien. Alles sind Dateien.
Da auch „Verzeichnisse“ Dateien sind und diese standardmäßig 2 Hardlinks besitzen (nämlich „.“ und „..“) würden bei einer find-Suche mit -links +1 auch alle Verzeichnisse angezeigt. Diese Hardlinks werden einem Verzeichnis beim Erstellen zugewiesen und sind die einzigen. Der User kann ein Verzeichniss nicht weiter mit Hardlinks versehen.

Ob find nur nach Dateien oder Verzeichnissen suchen soll, kann mit dem Parameter
-type f für nur Files
-type d für nur Verzeichnisse
vorgegeben werden. Mit ! kann eine solche Angabe auch negiert werden.
Eine Suche mit find über mehr als einen Hardlink ohne Berücksichtigung von Verzeichnissen könnte z.B.: so lauten

Am Beispiel von fdupes: Hrdlinks und Backup mit rsync mit dem iso-Image wäre die Ausgabe wie folgt:

Es ist egal, von wo aus man eine find-Suche startet.
Möchte man z.B.: alle Dateien im Verzeichnis „Downloads“ finden, welche weiter verlinkt sind, so gibt man bei obigen Beispiel

ein un bekommt folgende Ausgabe

Verkettung von Befehlen mit find:
Man kann den find-Befehl auch mit weiteren Befehlen verketten.
Eine Verkettung von find mit rm löscht alle gefundenen Dateien und könnte , zum obigen Beispiel, so aussehen:

Befindet sich im Ordner eine Datei, welche mehr als einen Hardlinks besitzt, wird diese gelöscht. Sie existiert danach ja noch, weil sie einen weitern Eintrag in ein anderes Verzeichnis besitzt.

Diesen Befehl kann man auch bei Hardlinks im gleichen Verzeichnis verwenden.
Beispiel:
Wenn man eine Datei mit einem Browser herunterlädt, wird diese meist im Ornder „Downloads“ abgelegt.
Lädt man diese Datei (aus Versehen) ein weiteres mal herunter, weisen aktuelle Browser oftmals nicht darauf hin, dass diese Datei schon existiert, sondern speichern diese ein weiteres mal mit einem anderen Namen ab.
Im folgenden Fall haben wir die eine Datei mehrfach heruntergeladen und das Verzeichniss könnte so aussehen:

Mit dem Befehl fdupes /data/Downloads -L würden diese 4 Dateien mit Hardlinks miteinander verkettet.
Die Ausgabe mit find würde folgendes Ergebnis liefern

Eine Verkettung von diesen, obigen find-Befehl mit rm würde nun jede Datei mit mehr als einen Hardlink löschen.
Durch die obige Ausgabe könnte man jetzt annehmen, dass alle Dateien gelöscht werden würden.
Das trifft aber nicht zu.
Der find-Befehl wird „live“ ausgeführt.
Das heißt, dass in diesem Fall der find-Befehl die Datei Bild.jpg findet, da sie mehr als einen Hardlink besitzt, und würde diese durch -exec rm löschen.
Danach findet find die Datei Bild(2).jpg mit ebenfalls mehr als einen Hardlink und löscht diese.
Gleiches glt auch für die Datei Bild(3).jpg und sie wird gelöscht.
Die Datei Bild(4).jpg würde jetzt aber nicht mehr gefunden werden, da dies der letzte Hardlink zu der Datei wäre – genauer: der Einzige.
Der Befehl find sucht aber nach Dateien mit mehr als einen Hardlink. Somit würde die Datei Bild(4).jpg nicht gelöscht werden.
Im Gegensatz zu Befehlen wie rsync oder fdupes, welche eine Dateiliste erstellen und diese dann abarbeiten, arbeitet find „live“ und arbeitet sofort nach erfolgtem Treffer den -exec-Befehl ab.
Danach fährt find mit dem angegebenen Paramtern fort und behandelt nachfolgende Treffer unabhängig.