我有一个文件夹,其中包含一定数量的具有硬链接的文件(在同一文件夹或其他位置),并且我想取消对这些文件的硬链接,以使它们变得独立,并且对其内容的更改不会影响任何文件。其他文件(其链接计数变为1)。
下面,我给出一个解决方案,该解决方案基本上将每个硬链接复制到另一个位置,然后将其移回原位。
但是,此方法似乎很粗糙且容易出错,因此我想知道是否有一些命令可以为我取消硬链接。
粗略的回答:
查找具有硬链接的文件(编辑:要查找具有硬链接的套接字等,请使用find -not -type d -links +1
):
find -type f -links +1 # files only
find -not -type d -links +1 # files, sockets etc.
取消硬链接的粗略方法(将文件复制到另一个位置,然后将其移回):
编辑: 正如Celada所说,最好在下面执行cp -p以避免丢失时间戳和权限。 编辑: 创建一个临时目录并将其复制到该目录下的文件中,而不是覆盖临时文件,尽管该mv
命令仍然存在风险(感谢@Tobu),但它将使覆盖某些数据的风险降到最低。 编辑: 尝试在同一文件系统(@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
因此,要取消硬链接所有硬链接(编辑:更改-type f
为-not -type d
,请参见上文):
find -not -type d -links +1 -print0 | xargs -0 unhardlink.sh
cp -i
开关运行此命令时,即使tmpfile应该提供唯一的文件名,它也会向我吐出几条消息询问是否应覆盖./fileXXXXXX
($temp
文件),因此必须处于某种竞争状况或其他任何情况,并有失去一些数据的风险。
unhardlink.sh
应该在包含需要取消链接的文件的同一目录内创建一个临时目录。否则,您的递归调用可能会在另一个文件系统内递归,并且由于临时目录位于当前工作目录中,因此最终您会在文件系统边界上移动内容。我想您可以将其"$(dirname "$i")/hardlink-XXXXXX"
作为参数传递给mktemp。
fuse
文件系统,则它实际上可能分派path/to/hardlink-XXX
到与之外的其他物理存储介质上path/to/original-file
,但是对此并没有太多的事情要做。