Question

This question already has an answer here:

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.

Was it helpful?

Solution

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

OTHER TIPS

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

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.

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top