#!/bin/sh # Replicates a directory with minimal space: all files are hardlinked, # rest is copied. #(c) Hans-Peter-Stoerr (www.stoerr.net) Jan 2004 #$Id: hardlndir,v 1.1 2004/01/08 08:26:34 stoerr Exp $ fromdir=$1 todir=$2 if test -z "$2"; then echo $0: usage: $0 fromdir todir echo replicates fromdir to todir by hardlinking files exit 3 fi mkdirhier "$todir" || exit 3 #create all directories find "$fromdir" -mindepth 1 -type d -printf '%P\000' \ | (cd "$todir"; xargs -r -0 mkdir -p) #(hard)link all files # This is not entirely correct: it would not link # dirnames with newlines. But bash seems to have a bug # when we do something like # find . -print0 | (while read -d '\000' -r fn; do echo $fn; done) find "$fromdir" -type d -printf '%P\n' \ | ( while read -r dirname; do find "$fromdir/$dirname" -mindepth 1 -maxdepth 1 -type f -print0 \ | xargs -r -0 ln -f "--target-directory=$todir/$dirname" done ) #Copy symlinks # TODO: doesn't handle names with newlines so far. # What the heck, rsync does this afterwards set -x find "$fromdir" -type l -printf '%l\n%P\n' \ | (while read -r linkto; do read -r link; ln -s "$linkto" "$link"; done) #catch all: copy the rest, correct dirtimes rsync -axHSW "$fromdir/." "$todir/."