就地断开硬链接?


13

我将我的点文件保留在版本控制下,部署它们的脚本会创建硬链接。我也习惯etckeeper将我/etc置于版本控制之下。最近我收到了这样的警告:

warning: hard-linked files could cause problems with bzr

简单的副本(cp filename.ext filename.ext)不起作用:

cp: `filename.ext' and `filename.ext' are the same file

重命名/移动文件(跨卷除外)也不会破坏硬链接。

所以我的问题是:是否有一种方法可以在不真正知道该文件的其他硬链接在哪里的情况下,断开与该文件的硬链接?


2
“ rm”命令断开硬链接。
Johan 2013年

Answers:


14
cp -p filename filename.tmp
mv -f filename.tmp filename

使其可编写脚本:

dir=$(dirname -- "$filename")
tmp=$(TMPDIR=$dir mktemp)
cp -p -- "$filename" "$tmp"
mv -f -- "$tmp" "$filename"

首先进行复制,然后再将其移动到位,具有以下优点:文件从原子上从硬链接更改为单独的副本(没有时间点filename是部分或丢失)。


7

您可能是想将硬链接拆分为单独的独立文件。

mv hardlink tempname && cp tempname hardlink && rm tempname

硬链接是目录中的条目与磁盘上的inode块之间的连接。

索引节点存储文件元数据,对于较小的文件,某些文件系统将数据存储在索引节点中,否则将指向数据块的指针存储,对于非常大的文件,将间接和双间接指针列表存储到磁盘分配单元。

无论如何,文件名(这是ls命令产生的内容)与存储此元数据的inode块之间的连接称为硬链接。

具有到单个文件的多个硬链接意味着由多个目录条目引用的同一个索引节点,可能在不同的目录中(在单个文件系统上)

rm从目录中删除文件名条目。一旦一个索引节点不再被任何文件引用,它的空间就会被释放以供其他文件使用。


确实。这就是cpmv示例所隐含的含义。因此,我无法使用临时文件。
0xC0000022L13年

@ 0xC0000022L,否,索引节点不包含指向其他索引节点的指针。仅用于数据块(如果对象很小,它们可以用作数据空间的两倍)。
vonbrand

4
确保复制时保留了权限和其他数据,即 使用cp -a(至少是GNU coreutils)。
vonbrand 2013年

@ 0xC0000022L,如果仔细看,原始文件只有一个临时名称,只有在最后一步才会创建一个新文件。
vonbrand 2013年

@vonbrand的确可以,取决于所使用的文件系统。
Johan 2013年

4

将其放在〜/ .bashrc文件的末尾。

delink () { tmpfile="$1$(date)"; cp -a "$1" "$tmpfile"; mv "$tmpfile" "$1"; }

这样运行

delink filename

3

使用bash脚本执行此操作的最佳方法是:

if [ -f "$1" ] ; then
dir="$(dirname -- "$1")"
tmpfile="$(mktemp --tmpdir="$dir")"
cp --preserve=all -f -- "$1" "$tmpfile"
mv -f -- "$tmpfile" "$1"
fi

注意事项:

  • 在尝试复制文件之前检查文件是否为常规文件
  • 将旧文件保留在原处,直到副本准备就绪
  • 用于mktemp生成保证不存在的文件
  • 用于-f强制覆盖--preserve=all并使元数据尽可能与原始文件相似
  • 使用--"引用包含空格和/或以开头的路径-

当前(3.16)的linux系统调用无法在不创建临时文件的情况下进行替换:虽然可以原子地覆盖文件(即,删除旧文件并通过一次操作替换为新文件),但是无法在文件系统上没有名称的文件(即使用功能O_TMPFILE标记创建的临时文件open)中执行此操作,因为该rename功能需要文件名作为输入(没有版本rename将文件描述符作为输入- 详情请看这里


1
请注意,您未能在dirnamemktemp呼叫中引用名称。解决了这个问题……
derobert 2014年

@derobert哦,谢谢,但是由于嵌套的双引号,这将无法工作...需要另一种解决方法!Kinda讨厌bash
pqnet 2014年

3
由于$( ... )-style命令替换,它将起作用。它比` ... `-style 更好的原因之一。
derobert

@derobert很好,不知道。另外,如何在内联代码标签中使用`?
pqnet 2014年

您可以使用反斜杠将其转义。因此,`输入以下内容即可`\``:(当然,我对其进行了两次转义操作,以显示您的输入内容)。
derobert

-1

您要查找的命令是 unlink


也许我的问题不清楚,但是通过“就地”以及带有cp和的示例mv,我想表明我希望文件在以后存在。
0xC0000022L13年

啊,我不清楚,不。那你应该去听约翰的回答。
詹妮·D

1
命令“ unlink”仅删除文件(unlink()系统调用执行的操作)。
劳尔·萨利纳斯-蒙塔古多

-1

如果要查找与该文件进行硬链接的所有文件名,则可以使用:

find -samefile myknowhardlinkfile

还会ls -il myknowhardlinkfile显示硬链接到相同inode(第三字段)的文件名数量。

101612442 -rw-rw-r--. 2 me me 0 Aug  5 07:07 myknowhardlinkfile

尽管这可能有用,但实际上并不能回答问题。
Flimm
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.