Ho una cartella che contiene un certo numero di file che hanno collegamenti fissi (nella stessa cartella o altrove) e desidero scollegare questi file in modo che diventino indipendenti e le modifiche al loro contenuto non influiranno su altro file (il loro conteggio dei collegamenti diventa 1).
Di seguito, fornisco una soluzione che sostanzialmente copia ogni collegamento reale in un'altra posizione, quindi lo sposta di nuovo in posizione.
Tuttavia, questo metodo sembra piuttosto rozzo e soggetto a errori, quindi mi piacerebbe sapere se esiste un comando che scollegherà un file per me.
Risposta grezza:
Trova file con collegamenti fissi ( Modifica : per trovare anche socket ecc. Con collegamenti fissi, utilizzare find -not -type d -links +1
):
find -type f -links +1 # files only
find -not -type d -links +1 # files, sockets etc.
Un metodo grezzo per de-hardlink di un file (copiarlo in un'altra posizione e spostarlo indietro):
Modifica: Come ha detto Celada, è meglio fare un cp -p di seguito, per evitare di perdere timestamp e autorizzazioni. Modifica: crea una directory temporanea e copia in un file al suo interno, invece di sovrascrivere un file temporaneo, riduce al minimo il rischio di sovrascrivere alcuni dati, sebbene il mv
comando sia ancora rischioso (grazie a @Tobu). Modifica: prova a creare la directory temporanea nello stesso filesystem (@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
Quindi, per annullare il collegamento di tutti gli hard link ( Modifica : modificato -type f
in -not -type d
, vedi sopra):
find -not -type d -links +1 -print0 | xargs -0 unhardlink.sh
cp -i
interruttore, sputato verso di me un paio di messaggi chiedendo se deve ignorare ./fileXXXXXX
(il $temp
file), anche se tmpfile dovrebbe dare nomi di file univoci, quindi non deve essere una sorta di condizione di gara o altro, e con essa il rischio di perdere alcuni dati.
unhardlink.sh
dovrebbe creare la directory temporanea all'interno della stessa directory che contiene il file che deve essere unhardlinked. Altrimenti la tua chiamata ricorsiva potrebbe ricorrere all'interno di un altro filesystem e finirai per spostare roba oltre i confini del filesystem perché la tua directory temporanea è nella directory di lavoro corrente. Immagino che potresti passare "$(dirname "$i")/hardlink-XXXXXX"
come argomento a mktemp invece.
fuse
filesystem, potrebbe effettivamente essere inviato path/to/hardlink-XXX
a un supporto di archiviazione fisico diverso da quello path/to/original-file
, ma non c'è molto che si possa fare al riguardo.