Tente isto:
#!/bin/sh
srcdir="$1"
dstdir="$2"
if [ -h "$srcdir" ]; then
val='readlink "$srcdir"'
if [ ! -h "$dstdir" ]; then
rm -rf "$dstdir"
fi
ln -s "$val" "$dstdir"
elif [ -d "$srcdir" ]; then
if [ ! -d "$dstdir" ]; then
rm -rf "$dstdir"
fi
mkdir "$dstdir"
for i in 'ls -1A "$srcdir"'; do
$0 "$srcdir/$i" "$dstdir/$i"
done
touch -a -r "$srcdir" "$dstdir"
touch -m -r "$srcdir" "$dstdir"
else
if [ ! -f "$dstdir" ]; then
rm -rf "$dstdir"
fi
ln "$srcdir" "$dstdir"
fi
Isso não lida com arquivos "especiais" como dispositivos de bloco, pipes nomeados, soquetes, etc.