A situação é complicada. Imagine o máximo de links é 5 e você tem 12 arquivos
a01
to a12
todos ligados em conjunto. Você precisa dividir a01..a05
e a06..a10
e a11..a12
, onde a06
e a07
etc ainda são vinculados, mas não a a01
.
Aqui está um script bash usando rsync
que é executado em um diretório de origem de exemplo ( src=/usr/libexec/git-core/
) no meu sistema que possui 110 hard-links. Ele simula um número máximo de 50 links ( max
) no diretório de destino realdest
pela função sim
. Em um caso real, você simplesmente ignoraria os erros muitos links e não usaria essa função.
Após o rsync inicial normal (com erros), a lista de arquivos ausentes é criada usando rsync -ni
, extraindo os nomes dos arquivos na função calctodo
into /tmp/todo
.
Existe então um loop em que rsync
dos arquivos ausentes, novamente ignorando muitos links erros (o que você teria se tivesse mais de 2*175
links no diretório original). Os arquivos criados com sucesso são linkados entre si.
A nova lista de arquivos ausentes é calculada. Isso é repetido até que não haja mais arquivos.
src=/usr/libexec/git-core/
realdest=/tmp/realdest
#rm -fr "$realdest"
max=50
sim(){
find ${1?} -links +$max |
sed "1,${max}d" |
xargs --no-run-if-empty rm
}
calctodo(){
sed -n '/^hf/{ s/[^ ]* //; s/ =>.*//; p }' >/tmp/todo
}
rsync -aHR "$src" "$realdest"; sim "$realdest"
rsync -niaHR "$src" "$realdest" | calctodo
while [ -s /tmp/todo ]
do mv /tmp/todo /tmp/todo.old
rsync -aHR --files-from=/tmp/todo.old / "$realdest"; sim "$realdest"
rsync -niaHR --files-from=/tmp/todo.old / "$realdest" | calctodo
done
Talvez seja necessário revisar isso se você tiver nomes de arquivo com "= >", novas linhas e assim por diante.
Note que você pode encontrar o número máximo de links suportados por um sistema de arquivos
getconf LINK_MAX /some/directory