Ich habe einen Ordner, der eine bestimmte Anzahl von Dateien enthält, die feste Links haben (im selben Ordner oder an einem anderen Ort), und ich möchte die Verknüpfung dieser Dateien aufheben, damit sie unabhängig werden und Änderungen an ihrem Inhalt keine Auswirkungen haben andere Datei (ihre Linkanzahl wird 1).
Im Folgenden gebe ich eine Lösung an, bei der jeder feste Link an einen anderen Ort kopiert und dann wieder an seinen Platz verschoben wird.
Diese Methode scheint jedoch ziemlich grob und fehleranfällig zu sein, daher würde ich gerne wissen, ob es einen Befehl gibt, der die Verknüpfung einer Datei für mich aufhebt.
Grobe Antwort:
Suchen Sie nach Dateien mit Hardlinks ( Bearbeiten : Um auch Sockets usw. mit Hardlinks zu finden, verwenden Sie find -not -type d -links +1
):
find -type f -links +1 # files only
find -not -type d -links +1 # files, sockets etc.
Eine grobe Methode, um die Verknüpfung einer Datei aufzuheben (sie an einen anderen Speicherort zu kopieren und zurückzuschieben):
Bearbeiten: Wie Celada sagte, ist es am besten, unten ein cp -p auszuführen, um zu vermeiden, dass Zeitstempel und Berechtigungen verloren gehen. Bearbeiten: Erstellen Sie ein temporäres Verzeichnis und kopieren Sie es in eine Datei darunter. Anstatt eine temporäre Datei zu überschreiben, wird das Risiko des Überschreibens einiger Daten minimiert, obwohl der mv
Befehl immer noch riskant ist (danke @Tobu). Bearbeiten: Versuchen Sie, das temporäre Verzeichnis im selben Dateisystem (@MikkoRantalainen) zu erstellen.
# This is unhardlink.sh
set -e
for i in "$@"; do
temp="$(mktemp -d -- "${i%/*}/hardlnk-XXXXXXXX")"
[ -e "$temp" ] && cp -ip "$i" "$temp/tempcopy" && mv "$temp/tempcopy" "$i" && rmdir "$temp"
done
So lösen Sie die Verknüpfung aller Hardlinks ( Bearbeiten : geändert -type f
in -not -type d
, siehe oben):
find -not -type d -links +1 -print0 | xargs -0 unhardlink.sh
cp -i
Schalter ausführte, ein paar Nachrichten an mich spuckte, in denen ich gefragt wurde, ob er./fileXXXXXX
(die$temp
Datei) überschreiben soll, obwohl tmpfile eindeutige Dateinamen geben sollte, also muss es eine Art Rennbedingung oder was auch immer sein, und damit das Risiko, einige Daten zu verlieren.unhardlink.sh
sollten ein temporäres Verzeichnis in demselben Verzeichnis erstellen, das die Datei enthält, die nicht verknüpft werden muss. Andernfalls wird Ihr rekursiver Aufruf möglicherweise in einem anderen Dateisystem wiederholt, und Sie verschieben Inhalte über Dateisystemgrenzen hinweg, da sich Ihr temporäres Verzeichnis im aktuellen Arbeitsverzeichnis befindet. Ich denke, Sie könnten"$(dirname "$i")/hardlink-XXXXXX"
stattdessen als Argument an mktemp übergeben.fuse
Dateisystem handelt, möglicherweise tatsächlichpath/to/hardlink-XXX
auf ein anderes physisches Speichermedium als gesendet wirdpath/to/original-file
, aber dagegen kann nicht viel getan werden.Antworten:
In Ihrem Skript gibt es Raum für Verbesserungen, z. B. das Hinzufügen einer
-p
Option zumcp
Befehl, damit Berechtigungen und Zeitstempel während des Unhardlink-Vorgangs erhalten bleiben, und Sie können eine Fehlerbehandlung hinzufügen, damit die temporäre Datei im Fehlerfall gelöscht wird. Die Grundidee Ihrer Lösung ist jedoch die einzige, die funktioniert. Um die Verknüpfung einer Datei aufzuheben, müssen Sie sie kopieren und dann wieder über den ursprünglichen Namen verschieben. Es gibt keine "weniger grobe" Lösung, und diese Lösung hat Race-Bedingungen für den Fall, dass ein anderer Prozess gleichzeitig auf die Datei zugreift.quelle
Wenn Sie Speicherplatz verbrennen möchten und eine relativ moderne Version von
tar
(z. B. Ubuntu 10.04 und CentOS 6) haben, können Sie mit dieser--hard-dereference
Option spielen.Etwas wie:
(wo ich gelaufen war
ln foo/[12] bar
)Von der Manpage:
quelle
cp -a --no-preserve=links /path/to/folder /path/to/copy && rm -rf /path/to/folder && mv /path/to/copy /path/to/folder
, wenn ich mich nicht irre. Ich denke, Ihre Methode wäre jedoch effizienter, da Teer weniger Festplattensuchen und damit weniger Thrashing beinhalten würde. Das gleiche könnte man mit rsync erreichen, mit noch geringerer Leistung als mit der cp-Methode :).tar cvf - --hard-dereference . | tar xf -
, es kann jedoch eine Race-Bedingung vorliegen, die dazu führt, dass Dinge explodieren. Ich habe es nicht versucht, und ich bin im Moment irgendwie nicht geneigt, dies zu tun.