什么是Unix命令来创build一个硬链接到OS X中的目录?

如何在OS X中创build一个指向目录的硬链接(而不是符号链接或Mac OS别名)? 我已经知道命令“目标目标”,但只有当目标是文件时才起作用。 我知道Mac OS与其他Unix环境不同,它允许硬链接到文件夹(例如Time Machine),但是我不知道如何自己做。

我同意,硬链接的文件夹/目录可能会导致问题,如果不小心,但他们有一个非常明确的优势 – 时间机器是一个很好的例子。 如果没有这些文件,那么冗余版本的文件将会很快耗尽即使是最大的磁盘也是不实际的。

只要你遵循阿米特·辛格(Amit Singh)的六条规则,雪豹就可以创build目录的硬链接:

  1. 文件系统必须loggingHFS +。
  2. 源和目标的父目录必须不同。
  3. 源的父项不能是根目录。
  4. 目的地不得在根目录中。
  5. 目的地不得成为来源的后代。
  6. 目的地不得有任何目录硬链接的祖先。

所以雪豹已经失去了创build硬链接到文件夹的能力,这是不正确的。

我只是validation了链接/取消链接在雪豹上的工作 – 只要你遵循六个规则。 我只是试了一下,它在我的Snow Leopard 10.6.6系统上工作正常 – 在引导卷和单独的USB外部卷上尝试过,并且在两种情况下都工作正常。

这是“hunlink.c”程序:

#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 

所以,如果你尝试一下,要小心 – 记住按照规则,并使用链接来创build这些硬链接,然后使用hunlink删除硬链接。 不要忘记logging你以后做了什么,或者为了其他可能需要知道这一点的人。

我刚刚了解到这些“硬链接”到文件夹的另一个“疑难杂症”。 当你创build它们的时候,Mac OS X的“幕后”确实发生了很多事情。一个非常重要的问题是,你创build链接的文件夹真的被移动到一个超级神奇的超级隐藏文件夹,名为/.HFS+私人电话号码簿数据%000d / dir_xxx其中xxx是“source_folder”的inode号 – 记住命令的格式是

 hlink source_folder target_folder 

因此,你必须小心不要在“source_folder”中打开任何文件,因为如果你这样做,他们只是被移动到超级魔法文件夹,如果你尝试保存任何改变,你可能会遇到一个问题到那些在“source_folder”中打开的文件。 这发生在我身上好几次,直到我明白发生了什么事情,解决办法很简单。 我注意到,如果没有得到原始“source_folder”中的所有文件夹/目录的有趣错误,但是您可以执行“ls”命令并且一切正常,则无法再执行“ls -la”命令。

如果你在“磁盘工具”程序中运行“validation磁盘”,你会注意到它可能会抱怨并给出了“卷位图需要对孤立块进行小修补”,这是创build超级魔法文件夹时发生的事情, “source_folder”的移动。

如果您发现自己处于“孤立块”的状态,请先将已更改的文件保存到不包含“source_folder”树的卷中的其他临时位置,然后使用“磁盘实用程序”卸载并重新装入包含“source_folder”或只是重新启动电脑。 然后将保存到临时位置的文件复制回原来的位置,然后重新开始工作。 这是为我工作,所以不能保证这也适用于你。 所以在一个有足够的备份的卷上试试这个可能是个好主意。

看起来非常奇怪,所有这些开销只是为了创build硬链接到一个文件夹的简单任务。 有没有人有任何想法为什么Mac OS X去这个硬链接创build文件夹这一努力? 这是否与“日志式”文件系统有关?

我通过阅读阿米特·辛格(Amit Singh)对他的“hfsdebug”实用程序的解释,发现了关于超级魔法,超级隐藏位置的信息。 如果你想了解更多的细节,请参阅他的网站Amit Singh的hfsdebug实用程序 。 这是一个非常有趣的软件,会告诉你很多有关HFS +文件系统的细节。 这是免费的,我鼓励你下载并尝试一下。 它不再被支持,但它仍然适用于雪豹和豹 – 基本上任何HFS +支持的系统。 因为它是一个“只读”工具,所以不能对它造成任何伤害 – 所以使用它来查看文件系统的一些细节是非常好的。

关于这些“硬链接到文件夹”的另一个问题 – 一旦你创build一个超级神秘的超级秘密隐藏文件夹被创build,这是很好的。 即使您将首先导致创build的文件夹取消关联,此魔术文件夹仍然存在。 不知道为什么,但确实如此。 如果你想尝试一下,你可以使用“hfsdebug”来查找。 您还可以使用“hfsdebug”来查明驱动器上存在多less这些“硬链接到文件夹”。 有关这些详细信息,请参阅Amit关于“hfsdebug”实用程序的文章。

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

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

如果使用NFS来挂载远程客户端(并假定系统上具有作为本地HFS +文件系统的卷的NFS服务器),则不会出现这些问题(除了错误消息)。 这里不提供关于如何使用NFS来挂载卷的细节。 我使用了Dr. Marcel Bresink的一个名为“NFS Manager”的好程序来帮助在服务器和客户端上安装NFS。 你可以从他的网站上得到它 – 只需在你最喜欢的search引擎中search“Bresink NFS Manager”,但他有一个免费的试用版,所以你可以尝试之前,你买。 如果你想学习如何进行NFS安装,这并不是什么大事,但是“NFS Manager”使得设置起来非常简单,并且可以调整所有不同的设置来优化它。 他还有其他几个整洁的Mac OS X实用程序,这些实用程序的价格非常合理 – 一个名为“Hardware Monitor”的硬件监视器,可以监视和绘制诸如电源使用情况,CPU温度,风扇速度以及许多其他variables本地和远程Mac系统在很长一段时间内(从几分钟到几天)。 绝对值得检查,如果你是方便的实用程序。

有一点我注意到,NFS文件传输速度比通过法新社慢了大约20%,但是你的“里程数可能有所不同”,所以没有任何方法的保证,但是我宁愿有一些工作,即使我有支付20%的业绩,而没有任何工作。

苹果公司意识到硬链接和远程AFP文件系统的问题,他们把它称为AFP客户端的“实施限制” – 我更喜欢称之为它真正在我看来是 – 一个BUG! 我只希望下一个版本的Mac OS X能够解决这个问题,因为我真的很喜欢在有意义的时候能够使用硬链接到文件夹。

这些笔记是我自己的个人意见,我不保证其正确性,所以使用它们需要您自担风险。 有一个很好的备份,然后再玩这些“硬链接到文件夹”,以防万一发生不可预见的事情。 但是,如果您决定更深入地了解Mac OS X的这个有趣的方面,我希望您能玩得开心。

那么你不能直接在BASH中完成。 然而…我在这里find一篇文章,讨论如何间接地做到这一点: http : //www.mactech.com/articles/mactech/Vol.23/23.11/ExploringLeopardwithDTrace/index.html通过编译一个简单的小C程序:

 #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; } 

…并build立在Terminal.app与:

 $ gcc -o hlink hlink.c -Wall 

废话。 在10.5上,它会在手册页告诉你ln

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

所以是的:

  sudo ln -d existing_dir new_hard_link 

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

删除是一个不同的故事:如果你去通常的方式删除目录,你会删除内容。 所以你必须 “取消链接”目录:

  unlink new_hard_link 

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

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


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

 brew install hardlink-osx 

一旦安装,创build一个硬链接:

 hln [source] [destination] 

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

 hln -u destination 

代码在Github上提供给那些感兴趣的人: https : //github.com/selkhateeb/hardlink

是的,它是由内核和文件系统支持的,但是由于它并不是为了一般用途,所以不会暴露给shell。

您大概可以计算出Time Machine使用的API,并将它们包装在命令行工具中,但最好能够明确指出。

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

解决问题的解决方法与其他解决scheme不同。 我用rsync来创build文件夹的副本。 Rsync可以parsing符号链接并复制链接的文件。

这解决了我的问题,而不使用硬链接到目录。 如果你只是在处理一小部分文件,这实际上是一个简单的解决scheme。

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

简短的答案是你不能。 :)(除了可能作为根,当说你不应该更准确)。

Unix只允许一系列指向目录的链接 – “..”来自其所有的子目录,“。” 从内部。 其他任何东西都可能是一个非常困惑的目录树的配方。 这显然是Ken Thompson的devise决定。

(话虽如此,显然苹果的Time Machine确实做到了:))

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

另一个解决scheme是使用bindfs https://code.google.com/p/bindfs/可以通过端口安装:;

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

这也可以使用内置Perl(来自terminal)来完成,无需编译任何东西。 我的具体用例是Google Drive(不支持符号链接),所以下面的例子反映了用例。

要将您的“文档”文件夹链接到Google云端硬盘,以便同步:

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

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

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

你需要“根”来取消链接(请参阅“取消链接”perldoc)。

ln的OSX版本无法做到这一点,但正如其他答案中提到的那样,GNU版本的ln可以在自制程序中作为gln作为coreutils公式的一部分。 man gln列出了-d选项,并在富 man gln的答案中提供了特定于OSX的警告。 换句话说,它不适用于所有情况。 究竟决定它是否有效的问题在任何地方都没有明确的定义。

作为先决条件,安装coreutils

  brew install coreutils 

现在你可以做:

  sudo gln -d /original_folder /mirror_folder 

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

  sudo gunlink /mirror_folder 

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

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

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

在folder_path / *中* target_folder

它在OSX 10.9上为我工作

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

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