J'ai un dossier qui contient un certain nombre de fichiers qui ont des liens durs (dans le même dossier ou ailleurs), et je veux dissocier ces fichiers, afin qu'ils deviennent indépendants, et les modifications de leur contenu n'affecteront aucun autre fichier (leur nombre de liens devient 1).
Ci-dessous, je donne une solution qui copie essentiellement chaque lien dur vers un autre emplacement, puis le remets en place.
Cependant, cette méthode semble plutôt grossière et sujette aux erreurs, donc j'aimerais savoir s'il existe une commande qui supprimera le lien physique d'un fichier pour moi.
Réponse grossière:
Rechercher des fichiers qui ont des liens durs ( Éditer : pour trouver également des sockets etc. qui ont des liens durs , utilisez find -not -type d -links +1
):
find -type f -links +1 # files only
find -not -type d -links +1 # files, sockets etc.
Une méthode grossière pour supprimer le lien physique d'un fichier (copiez-le vers un autre emplacement et déplacez-le en arrière):
Modifier: Comme Celada l'a dit, il est préférable de faire un cp -p ci-dessous, pour éviter de perdre les horodatages et les autorisations. Modifier: créez un répertoire temporaire et copiez-le dans un fichier en dessous, au lieu d'écraser un fichier temporaire, cela minimise le risque d'écraser certaines données, bien que la mv
commande soit toujours risquée (merci @Tobu). Modifier: essayez de créer le répertoire temporaire dans le même système de fichiers (@MikkoRantalainen).
# 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
Donc, pour dissocier tous les liens physiques ( Modifier : changé -type f
en -not -type d
, voir ci-dessus):
find -not -type d -links +1 -print0 | xargs -0 unhardlink.sh
cp -i
commutateur, il m'a craché quelques messages lui demandant s'il devait remplacer ./fileXXXXXX
(le $temp
fichier), même si tmpfile devrait donner des noms de fichier uniques, il doit donc y avoir être une sorte de condition de concurrence ou autre, et avec elle le risque de perdre certaines données.
unhardlink.sh
devez créer un répertoire temporaire dans le même répertoire qui contient le fichier qui doit être non lié. Sinon, votre appel récursif risque de rentrer dans un autre système de fichiers et vous finirez par déplacer des éléments au-delà des limites du système de fichiers car votre répertoire temporaire se trouve dans le répertoire de travail actuel. Je suppose que vous pourriez "$(dirname "$i")/hardlink-XXXXXX"
plutôt passer l'argument à mktemp.
fuse
système de fichiers, il peut en fait être distribué path/to/hardlink-XXX
sur un autre support de stockage physique path/to/original-file
, mais il n'y a pas grand-chose à faire à ce sujet.