关于macos:在OS X中创建指向目录的硬链接的Unix命令是什么?

关于macos:在OS X中创建指向目录的硬链接的Unix命令是什么?

What is the Unix command to create a hardlink to a directory in OS X?

如何在OS X中创建指向目录的硬链接(而不是符号链接或Mac OS别名)? 我已经知道命令"ln target destination",但只有在目标是文件时才有效。 我知道Mac OS与其他Unix环境不同,它允许硬链接到文件夹(例如,这用于Time Machine),但我不知道如何自己做。


我同意硬链接文件夹/目录如果不小心会引起问题,但它们有一个非常明确的优势 - Time Machine就是一个很好的例子。如果没有它们,它就变得不实际,因为冗余版本的文件的复制会很快消耗掉最大的磁盘。

只要您遵循Amit Singh的六条规则,Snow Leopard就可以创建到目录的硬链接:

  • 文件系统必须记录HFS +。
  • 源和目标的父目录必须不同。
  • 源的父级不能是根目录。
  • 目标不能位于根目录中。
  • 目的地不得是来源的后代。
  • 目的地不得有任何祖先,这是一个目录硬链接。
  • 所以Snow Leopard失去了创建硬链接的能力是不正确的
    文件夹。

    我刚刚确认链接/取消链接可以在Snow Leopard上运行 - 只要你遵循六个
    规则。我刚试过它,它在我的Snow Leopard 10.6.6系统上工作正常 - 在启动卷和单独的USB外部卷上试用它,它在两种情况下都能正常工作。

    这是"hunlink.c"计划:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdio.h>
    #include <unistd.h>
    int
    main(int argc, char *argv[])
    {
       if (argc != 2)
          return 1;
       int ret = unlink(argv[1]);
       if (ret != 0)
          perror("unlink");
       return ret;
    }

    gcc -o hunlink hunlink.c

    因此,如果您尝试它,请小心 - 记住遵循规则并使用hlink创建这些硬链接,然后使用hunlink删除硬链接。并且不要忘记记录
    你为以后做了什么,或为其他可能需要知道这一点的人做了什么。

    另一个"问题",我刚刚了解到文件夹的这些"硬链接"。当你创建它们时,真的有很多事情发生在Mac OS X的"幕后"。一个非常重要的问题是你创建链接的文件夹真的被移动到一个名为/.HFS+的超级神奇的超级隐藏文件夹专用目录数据%000d / dir_xxx其中xxx是"source_folder"的inode编号 - 记住命令的格式是

    1
    hlink source_folder target_folder

    因此,你必须小心不要在"source_folder"中打开任何文件,因为如果你这样做,他们只是被移动到超级魔法文件夹,如果你尝试保存任何更改,你可能会遇到问题到那些在"source_folder"中打开的文件。这件事发生在我身上几次,直到我突然意识到发生了什么,解决方案非常简单。我注意到你不能再执行"ls -la"命令而不会对原始"source_folder"中的所有文件夹/目录产生有趣的错误,但是你可以执行"ls"命令并且看起来都很好。

    如果您在"磁盘工具"程序中运行"验证磁盘",您会注意到它可能会抱怨并提供"卷位图需要对孤立块进行小修复",这就是创建超级魔法文件夹所发生的事情。"source_folder"移动到它。

    如果您确实发现自己遇到"孤立块",请先将更改的文件保存到不在包含"source_folder"树的卷中的其他临时位置,然后使用"磁盘工具"卸载并重新装入包含"孤立块"的卷。"source_folder"或只是重新启动计算机。然后将保存到临时位置的文件复制回原始位置,您应该重新开始营业。这对我有用,所以不能保证这对你也有用。所以最好在一个卷上试一试,以备不时之需。

    看起来非常奇怪,所有这些开销仅仅是为了创建文件夹的硬链接的简单任务。有没有人知道为什么Mac OS X为创建文件夹的硬链接而付出了所有这些努力?它是否与"日记"文件系统有关?

    通过阅读Amit Singh对他的"hfsdebug"实用程序的解释,我发现了关于超级神奇,超隐藏位置的信息。如果您想了解更多详细信息,请访问他的网站Amit Singh的hfsdebug实用程序。这是一个非常有趣的软件,它会告诉你很多关于HFS +文件系统的细节。这是免费的,我鼓励你下载并尝试一下。它不再受支持,但它仍适用于Snow Leopard和Leopard - 基本上任何支持HFS +的系统。你不能真正对它造成任何伤害,因为它是一个"只读"工具 - 所以用它来查看文件系统的一些细节是很好的。

    关于这些"文件夹的硬链接"的另一个问题 - 一旦你创建了一个并且创建了超级神奇的超级秘密隐藏文件夹,它就会存在。即使您取消导致首先创建它的文件夹的链接,这个魔术文件夹仍然存在。不知道为什么,但它确实如此。如果您想尝试一下,可以使用"hfsdebug"找到它。您还可以使用"hfsdebug"来查找驱动器中存在多少个"文件夹硬链接"。有关这些详细信息,请参阅Amit关于"hfsdebug"实用程序的文章。

    他还有另一个更新的实用程序,但支持成本。它被称为fileXray,对于个人非商业类型许可证,同一家庭中任意数量的计算机上的一个人花费79美元。它有一个173页的用户指南,你可以下载,看看它在你购买之前可以做些什么。不幸的是没有试用版,所以请阅读手册并查看网站了解更多详细信息,看看它是否可以帮助您解决问题。在他们的网站上了解有关它的所有详细信息 - 有关详细信息,请参阅fileXray网站。

    使用这些硬链接到文件夹时,您应该注意几个问题。如果将创建它们的卷安装到远程客户端,则可能存在严重问题,具体取决于它们的安装方式。如果您使用AFP将卷安装到远程客户端,则存在很大的问题,因为任何当前具有硬链接或曾经有一个但后来被删除的文件夹将无法用作所有较低级别的文件夹(将无法从Finder或终端窗口访问,但无法访问文件。如果您尝试执行简单的"ls -lR"命令,它将失败并为所有较低级别的文件夹提供"ls:xxx:No such file or directory"错误消息。如果使用Finder窗口遍历远程卷的目录树,则首次单击文件夹名称时,文件夹中具有或具有硬链接的文件夹将立即消失,而不会出现任何错误。

    如果使用NFS挂载远程客户端(并假设系统上有一个NFS服务器将该卷作为本地HFS +文件系统),则似乎不会出现这些问题(错误消息除外)。此处未提供有关如何使用NFS安装卷的详细信息。我使用了来自Marcel Bresink博士的一个很好的程序,名为"NFS Manager"来帮助安装服务器和客户端上的NFS。你可以从他的网站上获取它 - 只需在你最喜欢的搜索引擎中搜索"Bresink NFS Manager",但他有一个免费试用版,所以你可以在购买前试用。如果你想学习如何进行NFS挂载,这并不是什么大不了的事,但是"NFS Manager"可以很容易地进行设置并调整所有不同的设置以帮助优化它。他还拥有其他几款价格非常合理的Mac OS X实用程序 - 一种名为"硬件监视器"的功能,可让您监控和绘制各种功能,如电源使用率,CPU温度,风扇速度以及许多其他变量。本地和远程Mac系统在很长一段时间内(从几分钟到几天)。如果您使用便利的实用程序,绝对值得一试。

    我注意到的一件事是NFS文件传输速度比通过AFP减少大约20%,但是你的"里程可能会有所不同",所以不能保证这种方式或其他方式,但我宁愿有一些东西可以工作,即使我有与没有任何工作相比,支付20%的性能。

    Apple意识到硬链接和远程AFP文件系统的问题,他们将其称为AFP客户端的"实施限制" - 我更喜欢称之为我真正看来的 - 一个BUG!我只希望Mac OS X的下一个版本能解决这个问题,因为我真的很想在有意义的时候使用硬链接到文件夹。

    这些说明是我个人的意见,我不保证其正确性,因此使用它们需要您自担风险。 在玩这些"文件夹的硬链接"之前,请先进行良好的备份,以防发生意外情况。 但是如果您决定进一步了解Mac OS X的这个有趣方面,我希望您玩得开心。

    好。


    你不能直接在BASH中做到这一点。但是......我在这里发现了一篇文章,通过编译一个简单的小程序来讨论如何间接地做到这一点:http://www.mactech.com/articles/mactech/Vol.23/23.11/ExploringLeopardwithDTrace/index.html:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <unistd.h>
    #include <stdio.h>

    int main(int argc, char *argv[])
    {
       if (argc != 3) return 1;

       int ret = link(argv[1], argv[2]);

       if (ret != 0) perror("link");

       return ret;
    }

    ...并在Terminal.app中构建:

    1
    $ gcc -o hlink hlink.c -Wall


    废话。在10.5,它告诉你在手册页中的ln:

    1
    2
    3
    4
       -d, -F, --directory
              allow the superuser to attempt to hard link  directories  (note:
              will  probably  fail  due  to  system restrictions, even for the
              superuser)

    是的:是的

    1
        sudo  ln  -d  existing_dir  new_hard_link

    给它你的密码,你还没有完成。你没有记录它,是吗?您必须记录硬链接目录;即使它是单个用户机器。

    删除是一个不同的故事:如果你去删除目录的常用方法,你将删除内容。所以你必须"取消链接"目录:

    1
        unlink  new_hard_link

    那里。希望你不要破坏你的文件系统!


    交叉发布这个很好地解决问题的好工具,最初由Sam发布:

    要安装Hardlink,请确保已安装自制软件,然后运行:

    1
    brew install hardlink-osx

    安装后,创建一个硬链接:

    1
    hln [source] [destination]

    我还注意到unlink命令在雪豹上不起作用,所以我添加了一个取消链接的选项:

    1
    hln -u destination

    Github上的代码可供感兴趣的人使用:https://github.com/selkhateeb/hardlink


    是的,它受内核和文件系统的支持,但由于它不适用于一般用途,因此它不会暴露给shell。

    您可以找出Time Machine使用的API并将它们包装在命令行工具中,但最好还是明确地提示并引导它。


    OSX版本的ln不能这样做,但是,正如富人的另一个答案中所提到的,GNU版本的ln可以作为coreutils公式的一部分在homebrew中作为gln提供。 man gln列出了-d选项,并在rich的答案中提供了特定于OSX的警告。 换句话说,它并不适用于所有情况。 究竟是什么决定它是否有效似乎没有记录在任何地方。

    作为先决条件,安装coreutils

    1
        brew install coreutils

    现在你可以这样做:

    1
        sudo gln -d /original_folder /mirror_folder

    重要提示:要删除硬链接,您必须使用gunlink

    1
        sudo gunlink /mirror_folder

    使用rm或Finder也将删除原始文件夹。

    仅供参考:coreutils自制软件公式提供了通用unix工具的GNU兼容版本。 使用brew list coreutils查看完整列表。


    截至2018年不再可能。 APFS(在MacOS High Sierra 10.13中引入)与目录硬链接不兼容。 请参阅https://github.com/selkhateeb/hardlink/issues/31


    我的情况是,我发现从Windows虚拟机,我不能遵循符号链接。 (我想在Internet Explorer中测试一些HTML页面)。我的目录结构有CSS和图像文件夹的符号链接。

    我解决问题的解决方法与其他暗示的方法不同。我用rsync创建了该文件夹的副本。 Rsync可以解析符号链接并复制链接文件。

    这解决了我的问题,而没有使用目录的硬链接。如果您只处理一小组文件,它实际上是一个简单的解决方案。

    1
    rsync -av --copy-dirlinks --delete ../htmlguide ~/src/

    这也可以通过内置的Perl(来自终端)完成,无需编译任何内容。我的具体用例适用于Google云端硬盘(不支持符号链接),因此下面的示例反映了用例。

    要将"Documents"文件夹链接到Google云端硬盘,请将其同步:

    1
    perl -e 'link"/Users/me/Documents","/Users/me/Google Drive/Documents"'

    要从Google云端硬盘中删除指向"文档"文件夹的链接:

    1
    sudo perl -U -e 'unlink"/Users/me/Google Drive/Documents"'

    你需要"root"取消链接(参见"unlink"perldoc)。


    在Linux中,您可以使用bind mount来模拟硬链接目录。 OSX不确定

    1
    2
    sudo mount --bind /some/existing_real_contents /else/dummy_but_existing_directory
    sudo umount /else/dummy_but_existing_directory

    从链接到的文章中,如果您尝试在与原始目录相同的目录中创建硬链接,则会收到该错误。你必须在其他地方创建它。


    简短的回答是你不能。 :)(除非可能是root用户,否则更准确地说你不应该这样做。)

    Unix只允许一定数量的目录链接 -"..."来自其所有子目录和"。"。从内在本身。任何其他东西都可能是一个非常混乱的目录树的配方。这显然是Ken Thompson的设计决定。

    (话虽如此,显然Apple的Time Machine确实这样做:))


    如果没有子文件夹,你可以试试

    ln folder_path /*.* target_folder

    它在OSX 10.9上对我有用


    另一种解决方案是使用可通过端口安装的bindfs https://code.google.com/p/bindfs/:

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


    推荐阅读