I have a folder which contains a certain number of files which have hard links (in the same folder or somewhere else), and I want to de-hardlink these files, so they become independant, and changes to their contents won't affect any other file (their link count becomes 1).
Below, I give a solution which basically copies each hard link to another location, then move it back in place.
However this method seems rather crude and error-prone, so I'd like to know if there is some command which will de-hardlink a file for me.
Crude answer :
Find files which have hard links (Edit: To also find sockets etc. that have hardlinks, use find -not -type d -links +1
) :
find -type f -links +1 # files only
find -not -type d -links +1 # files, sockets etc.
A crude method to de-hardlink a file (copy it to another location, and move it back) :
Edit: As Celada said, it's best to do a cp -p below, to avoid loosing timestamps and permissions. Edit: Create a temporary directory and copy to a file under it, instead of overwriting a temp file, it minimizes the risk to overwrite some data, though the mv
command is still risky (thanks @Tobu). Edit: Try to create the temporary directory in the same 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
So, to un-hardlink all hard links (Edit: changed -type f
to -not -type d
, see above) :
find -not -type d -links +1 -print0 | xargs -0 unhardlink.sh