O primeiro problema é que o comando find
encontrará apenas links que usaram caminhos completos, não relativos. Para ilustrar:
$ ln -s /home/terdon/foo/NonExistantFile foo
$ ln -s NonExistantFile bar
$ tree
.
|-- bar -> NonExistantFile
'-- foo -> /home/terdon/foo/NonExistantFile
No exemplo acima, criei dois links quebrados. O primeiro usou um caminho absoluto e o segundo, um relativo. Se eu tentar o seu comando find
(com o comando echo
de relinking em vez de executá-lo para que possamos ver o que está fazendo), apenas um dos dois será encontrado:
$ find . -lname '/home/terdon/*' -exec \
sh -c 'echo ln -snf "/home$(readlink "$0")" "$0"' {} \;
ln -snf /home/home/terdon/foo/NonExistantFile ./foo
A segunda questão é que o seu caminho está errado. Você está recriando links como "/home$(readlink "$0")" "$0"
. O comando readlink
já mostrará o caminho completo, então adicionar /home
a ele resultará em /home/home/...
, que não é o que você deseja.
Mais importante, o que você está tentando não é possível. Se um link for quebrado, isso significa que seu destino não existe. Como o alvo não existe, você não pode simplesmente vincular novamente o arquivo, não há lugar para vinculá-lo a . A única coisa que você pode fazer é recriar o alvo do link. No entanto, é improvável que isso seja muito útil, pois isso simplesmente faria com que seus links quebrados apontassem para arquivos novos e vazios. Se isso é realmente o que você quer fazer, você poderia tentar
find . -type l -exec sh -c 'touch "$(readlink "{}")" ' \;
Finalmente, você pode querer criar um script mais complexo que i) encontre todos os links quebrados ii) procure em sua máquina arquivos com o mesmo nome que o destino do link iii) apresente uma lista deles e iv) pergunta-lhe qual deles deve agora vincular.