1

I'm using rsync to backup some of my files:

rsync -aEN --delete --link-dest="$CURR/" "$SOURCE/" "$NEW/"

The --link-dest option works fine with most files, but not with symlinks.
When I was writing a clean-up script for old backups, I noticed that unchanged symlinks are not hard-linked, but rather copied.

Now I'm wondering:
Is there a way to make rsync hard-link unchanged symlinks as well?
And if not: Is it intentional or a bug in rsync?

I'm using rsync version 3.1.1 on Mac OS 10.11.

Edit:

It seems to be a problem in Mac OS X. For some reason HFS+ seems not to support hard-links to symlinks.

Sven
  • 21

2 Answers2

4

The filesystem on macOS (HFS+) does not support hard links to symbolic links:

$ touch file
$ ls -l file
-rw-r--r-- 1 kk staff 0 Jun 17 18:35 file

$ ln -s file slink
$ ls -l file slink
-rw-r--r-- 1 kk staff 0 Jun 17 18:35 file
lrwxr-xr-x 1 kk staff 4 Jun 17 18:36 slink -> file

The following would ordinarily create a hard link to a symbolic link, and is even documented in the ln manual on macOS to do so (EDIT: no it isn't, unless you have GNU coreutils installed and read the wrong manual, doh!):

$ ln -P slink hlink
$ ls -l file slink hlink
-rw-r--r-- 1 kk staff 0 Jun 17 18:35 file
lrwxr-xr-x 1 kk staff 4 Jun 17 18:38 hlink -> file
lrwxr-xr-x 1 kk staff 4 Jun 17 18:36 slink -> file

You can see by the ref count (1) that no new name was created for slink (would have been 2 for both slink and hlink if it had worked). Also, stat tells us that hlink is a symbolic link with 1 inode link (not 2):

$ stat hlink
  File: 'hlink' -> 'file'
  Size: 4               Blocks: 8          IO Block: 4096   symbolic link
Device: 1000004h/16777220d      Inode: 83828644    Links: 1
Access: (0755/lrwxr-xr-x)  Uid: (  501/      kk)   Gid: (   20/   staff)
Access: 2016-06-17 18:38:18.000000000 +0200
Modify: 2016-06-17 18:38:18.000000000 +0200
Change: 2016-06-17 18:38:18.000000000 +0200
 Birth: 2016-06-17 18:38:18.000000000 +0200

EDIT: Since I was caught using GNU coreutils, here's the tests again with /bin/ln on macOS:

$ touch file
$ /bin/ln -s file slink
$ /bin/ln slink hlink   # there is no option corresponding to GNU's -P
$ ls -l file slink hlink
-rw-r--r--  2 kk  staff  0 Jun 17 18:59 file
-rw-r--r--  2 kk  staff  0 Jun 17 18:59 hlink
lrwxr-xr-x  1 kk  staff  4 Jun 17 18:59 slink -> file

The hard link is pointing to file rather than to slink.

On e.g. Linux and OpenBSD (the other OSes I use), it is possible to do this, which results in

$ ls -l file slink hlink
-rw-rw-r-- 1 kk kk 0 Jun 17 18:35 file
lrwxrwxrwx 2 kk kk 4 Jun 17 18:43 hlink -> file
lrwxrwxrwx 2 kk kk 4 Jun 17 18:43 slink -> file

(notice "2")

Kusalananda
  • 333,661
2

You cannot make hardlinks to symbolic links (this is not a "limitation" of OS X). A hardlink is a reference to an inode, and a symbolic link is not an inode but only an entry in the directory with some additional information.

You may be thinking of Windows, which has analogous features, which behave differently.

rsync does have a --copy-links option which tells it to copy the file to which a symbolic link points to the destination. That would be useful if you are trying to construct a complete replica of your source directory (but not very useful if your goal is to reduce disk usage).

Thomas Dickey
  • 76,765
  • I believe you're wrong. See my answer. – Kusalananda Jun 17 '16 at 16:47
  • Your example isn't in the manual page which I am reading. By the way, making comments like that is unfriendly. – Thomas Dickey Jun 17 '16 at 16:49
  • I am sorry, but I don't know how to put it in another way; I'm able to make hard links to symbolic links on Linux and on other Unices, but not on OS X HFS+. The manual says "-P, --physical make hard links directly to symbolic links", but that's not what's happening. – Kusalananda Jun 17 '16 at 16:52
  • 1
    My bad. It turns out I had the GNU coreutils installed. That's where that manual comes from. Still, I can create a hard link to a symbolic link on other OSes... – Kusalananda Jun 17 '16 at 16:56
  • 3
    It's a recent feature in POSIX, which doesn't appear to be documented for OSX. rsync isn't in POSIX, doesn't have to support new features. – Thomas Dickey Jun 17 '16 at 17:02
  • 1
    I don't see why it shouldn't be possible to create hard-links to symlinks. Anyway I just tested it on Linux and it worked fine. As for Windows, I don't know what features it offers. I've avoided it for the last 14 or so years. – Sven Jun 17 '16 at 17:11
  • 1
    It depends. The rsync program takes it into account (see log entry). – Thomas Dickey Jun 17 '16 at 17:24