在Mac OS X中创建目录硬链接

67

如何在Mac OS X中创建一个目录的硬链接?

这个功能已经被添加到他们的文件系统中Mac OS X v10.5(豹纹)(为了时间机器),但我没有找到任何有关从命令行实际使用它的信息。


2
如果您想了解如何从命令行作为用户访问此功能,则应将其放在SuperUser上。如果您想以编程方式执行此操作,那就是另一回事了 :-) - Joey
4个回答

87

如果有人感兴趣,我已经将建议答案打包到了一个Git存储库中:https://github.com/selkhateeb/hardlink

安装完成后,使用以下命令创建硬链接:

hln source destination

我还注意到在Mac OS X v10.6(Snow Leopard)上,unlink命令无法工作,因此我添加了一个选项以进行解除链接:

hln -u destination

要安装 Hardlink,请使用 Homebrew 并运行:

brew install hardlink-osx

2
谢谢。对我有用。但你应该把Jean-Philippe Pellet的评论添加到README中。 - Maciek Sawicki
5
值得注意的是,现在可以在Homebrew上找到这个软件。执行brew install hardlink-osx命令即可安装。 - Amir Abiri
1
谢谢@AmirAbiri,已添加。 - fregante
1
我注意到这里有一些有趣的事情。这种链接方法与普通的Unix/Linux硬链接不同——它涉及删除原始目录。Mac OS X 不允许我在链接仍然存在的情况下删除原始目录。 - Chris Prince
10
在 macOS 10.14 上,即使使用 sudo,似乎我仍然会收到“操作不允许”的错误。 - Swivel
显示剩余6条评论

75

不幸的是,苹果削弱了ln命令。 您可以使用以下程序创建指向目录的硬链接:

#include <unistd.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
 if (argc != 3) {
  fprintf(stderr,"Use: hlink <src_dir> <target_dir>\n");
  return 1;
 }
 int ret = link(argv[1],argv[2]);
 if (ret != 0)
  perror("link");
 return ret;
}

请注意,硬链接的目录可能不在同一个父目录下,所以您可以这样做:

$ gcc hlink.c -o hlink
$ mkdir child1
$ mkdir parent
$ ./hlink child1 parent/clone2

3
嘿,我已经使用这个东西有一段时间了 - 非常感谢。但是,我注意到如果我删除一个硬链接目录 (rm -rf),它也会擦除原始源目录的内容。这很合理,因为 rm -rf 逐个删除目录中的文件。然而,我想要能够直接删除硬链接。这可能吗? - Felix Geisendörfer
3
你尝试过使用unlink命令和系统调用吗? - Freeman
11
看起来他们修复了这个问题...在Snow Leopard上尝试时,我收到了“链接:操作不允许”的错误提示。 - taber
6
请确保在与源目录的父目录不同的目录中创建硬链接(例如,在Freeman的示例中的 parent/ 目录中)。这是http://osxbook.com/blog/2008/11/09/hfsdebug-40-and-new-hfs-features/中概述的限制之一。 - Jean-Philippe Pellet
4
在10.13.3(High Sierra)中,“链接”和“取消链接”函数均无法正常工作,导致出现“操作不允许”的错误。 - S_R
显示剩余4条评论

18

回答the_undefined的问题,如何删除一个硬链接到目录而不删除它链接到的其他目录的内容:据我所知,使用内置命令无法从命令行完成此操作。然而,以下这个程序(受Freeman帖子启发)可以完成此操作:

#include <unistd.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
    if (argc != 2) {
        fprintf(stderr,"Use: hunlink <dir>\n");
        return 1;
    }
    int ret = unlink(argv[1]);
    if (ret != 0)
        perror("unlink");
    return ret;
}

继续Freeman的例子,

$ gcc hunlink.c -o hunlink
$ echo "foo bar" > child1/baz.txt
$ ./hunlink parent/clone2

这将删除parent/clone2处的硬链接,但仅保留目录child1和文件child1/baz.txt


我收到了“资源繁忙”的错误。使用binds创建了硬链接。 - Alex Zubkov

13

另一种解决方法是使用bindfs https://code.google.com/p/bindfs/,可以通过端口进行安装:

sudo port install bindfs
sudo bindfs ~/source_dir ~/target_dir

这在我的Mojave v10.14.3上有效。 - rwcorbett
在Catalina上对我不起作用:mkdir aa; mkdir bb; bindfs aa bb会返回一个错误(无法解析挂载点“bb”:没有这样的文件或目录),我添加了一个github问题:https://github.com/mpartel/bindfs/issues/83 - Thomas
现在它在Catalina上运行得非常完美。(Thomas提到的问题已经解决了) - Sai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接