tags:

views:

1375

answers:

5

How can I create a hard link to a directory in OSX?

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

+4  A: 

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
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?
felixge
Have you tried the unlink command and system call?
Freeman
+1 (would give more if I could) This has totally saved my bacon!
Dave DeLong
Looks like they patched this up... tried this in Snow Leopard and I get "link: Operation not permitted"
taber
A: 

this is great thanks very much. I want to emphasize on that bit of unimportant looking shell script that shows you how to link two files and reminds not to try this in the same parent directory.... :)

joeschmoe
+1  A: 

In 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.

rleber
A: 

is rmdir exists for macosx? Google said that exists. try to use it.

Ivan
A: 

Ivan: rmdir only works on empty directories. The point of a hard link is that there are two directories, and their contents are exactly the same, and they are actually portals to the same structure on disk. You can't do rmdir any more than you can do rm -rf; hunlink sounds like the way to do it.

In linux, you could have done something like this:

#!/bin/bash
mkdir dest
mount -o bind src dest
umount dest
rmdir dest
Kingdon