66

How can I create a hard link to a directory in Mac OS X?

This feature has been added to their file system in Mac OS X v10.5 (Leopard) (for time machine), but I could not find any information on actually using it from the command line.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Felix Geisendörfer
  • 2,902
  • 5
  • 27
  • 36
  • 2
    This should be on SuperUser if you're interested in how to access this feature as a user from the commandline. If you'd want to do it programmatically that'd be a different story :-) – Joey Sep 16 '09 at 12:06

4 Answers4

87

I have bundled up the suggested answer in a Git repository if anybody is interested: https://github.com/selkhateeb/hardlink

Once installed, create a hard link with:

hln source destination

I also noticed that unlink command does not work on Mac OS X v10.6 (Snow Leopard), so I added an option to unlink:

hln -u destination

To install Hardlink, use Homebrew and run:

brew install hardlink-osx
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sam
  • 1,211
  • 9
  • 5
  • 2
    Thanks. Worked for me. But you should add Jean-Philippe Pellet comment do README. – Maciek Sawicki Feb 23 '12 at 16:20
  • @Sam : I'm on 10.6.8. Linking is working, but unlinking isn't. :( Any suggestions? – Jerry B May 01 '14 at 02:35
  • 5
    It's worth noting that this is now up on [Homebrew](https://github.com/Homebrew/homebrew/blob/master/Library/Formula/hardlink-osx.rb). `brew install hardlink-osx` – Amir Abiri Mar 31 '15 at 08:06
  • Also, it seems the binary is located at hln now, and thus the command to use is hln as opposed to hardlink. – Anthony Jul 08 '15 at 17:47
  • Works as of today for me for linking! – Chris Prince Jan 13 '16 at 21:24
  • 1
    I've noticed something interesting with this. This method of linking is quite different than a normal Unix/Linux hardlink-- in terms of removing the original directories. Mac OS X is *not* letting me remove the original directory with the links still in place. – Chris Prince Jan 19 '16 at 20:54
  • 1
    Hi after a directory is hard linked , is there a way to detect it is a hard link ? I want to do this to conditionally remove the hard links. – Tony Sep 24 '16 at 19:42
  • 10
    Hmmm... seems on macOS 10.14 I get the error "Operation not permitted" even with `sudo` – Swivel Jan 18 '19 at 05:51
  • 1
    Doesn't work with the new macOS as APFS doesn't allow folder hard links. Workaround is to use `bindfs` utility to mount the directory. See: https://github.com/selkhateeb/hardlink/issues/31 – jendas Apr 24 '19 at 08:33
  • 1
    brew removed the formula of hardlink-osx – Kirby Zhou Jan 23 '22 at 07:53
74

Unfortunately Apple has crippled the ln command. You can use the following program to create a hard link to a directory:

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

Take into account that the hard linked directories may not be in the same parent directory, so you can do this:

$ gcc hlink.c -o hlink
$ mkdir child1
$ mkdir parent
$ ./hlink child1 parent/clone2
Freeman
  • 5,810
  • 3
  • 47
  • 48
  • 3
    Hey, I've been using this for a while now - thanks a ton. However, I noticed that if I delete a hard linked directory (rm -rf) it will also wipe the contents of the original source dir. Makes sense since rm -rf goes through the dir and removes file by file. However, I'd like to have the ability to remove the hardlink directly. Is that possible? – Felix Geisendörfer Oct 20 '09 at 12:28
  • 3
    Have you tried the unlink command and system call? – Freeman Oct 22 '09 at 18:50
  • 1
    +1 (would give more if I could) This has totally saved my bacon! – Dave DeLong Feb 03 '10 at 20:53
  • 11
    Looks like they patched this up... tried this in Snow Leopard and I get "link: Operation not permitted" – taber May 19 '10 at 20:42
  • 6
    @taber: be sure to create the hard link in a directory different from the source directory's parent (e.g., in parent/ in Freeman's example). This is one of the restrictions outlined in http://osxbook.com/blog/2008/11/09/hfsdebug-40-and-new-hfs-features/ – Jean-Philippe Pellet Dec 06 '10 at 14:59
  • does anyone know how does timemachine treat hardlinks that exist on a volume being backed up? – 0cd Jul 03 '13 at 09:34
  • glad I found this. sorry to resurrect an old thread but this works well for me except for one problem. Finder doesn't want to refresh the content of a directory if I change something in the directory hardlinked to it. Tried on two different macs. is this normal or is this a Finder bug? 10.11.1. Relaunching Finder forces a refresh btw. – Vitali Kapovitch Oct 31 '15 at 21:08
  • 3
    A word of warning, apfs doesn't support hardlinks and converting your hfs+ to apfs wipes all the multilinked directories (converting them to files of 0 bytes). – Farcaller Feb 09 '18 at 12:58
  • 4
    Both "link" and "unlink" calls not working on 10.13.3 (High Sierra) resulting "Operation Not Permitted". – S_R Feb 13 '18 at 15:21
17

In the answer to the question by the_undefined about how to remove a hardlink to a directory without removing the contents of other directories to which it is linked: As far as I can tell, it can't be done from the command line using builtin commands. However, this little program (inspired by Freeman's post) will do it:

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

To follow on with Freeman's example,

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

will remove the hardlink at parent/clone2, but leave the directory child1 and the file child1/baz.txt alone.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rleber
  • 573
  • 3
  • 9
13

Another solution is to use bindfs https://code.google.com/p/bindfs/ which is installable via port:

sudo port install bindfs
sudo bindfs ~/source_dir ~/target_dir
Kit Sunde
  • 35,972
  • 25
  • 125
  • 179
  • this works for me on Mojave v10.14.3 – rwcorbett Apr 04 '19 at 19:35
  • doesn't work for me on Catalina: mkdir aa; mkdir bb; bindfs aa bb will return an error (Failed to resolve mount point `bb': No such file or directory ), I added a github issue: https://github.com/mpartel/bindfs/issues/83 – Thomas Mar 22 '20 at 13:57
  • It works flawlessly on Catalina now. (Issue Thomas mentioned is fixed) – Sai Sep 17 '20 at 20:15