Mac – cp -r -l in MacOS (recursive copy preserving hard links)

backupcpmacrsync

I'm trying to copy a directory tree recursively preserving hardlinks to the file. Using gnu cp, this would work with the -l flag. cp would then recreate the directory structure, but wouldn't need to copy the contents of each file.

This is preliminary to a backup, first I want to make a cheap (hardlinked) copy of the previous backup and then rsync the source directory over this copy. Roughly:

 cp -r -l yesterdays_backup todays_backup
 rsync -a source_dir todays_backup

Unfortunately, OSX's cp doesn't support the -l flag, as far as I can tell, cpio doesn't support recursive copying. The other alternative is pax, but that leads to the entire directory structure being copied:

 pax -rw backups/yesterdays_backup backups/todays_backup

transforms:

 yesterdays_backup
 |
  \source_dir (...)

to:

 todays_backup
 |
  \backups
          \yesterdays_backup
                            \source_dir(...)

There should be an easy/obvious way to do this, but I'm currently stumped…
Any alternatives to cpio and pax? I'd like to avoid having to install gnu cp.

I'm aware of Timemachine, but that won't properly back up encrypted directories incrementally.

Best Answer

It is easy enough to install cp from MacPorts, however, if you don't want to, or want to create a portable script, then you have three options:

rsync

rsync --archive --link-dest=../yesterdays_backup backups/yesterdays_backup\
   backups/todays_backup

cpio

mkdir backups/todays_backup
cd backups/yesterdays_backup
find . -print | cpio -p -al ../todays_backup

pax

mkdir backups/todays_backup
cd backups/yesterdays_backup
pax -rwl . ../todays_backup