Como posso “vincular” muitos links simbólicos quebrados?

50

Eu tenho uma árvore de diretórios que possui vários links simbólicos para arquivos em /home ... no entanto, movi /home para /mnt/home e preciso de uma maneira de "revincular" todos os links simbólicos. Essa funcionalidade existe ou eu preciso escrever um script para fazer isso?

Como exemplo, tenho algo parecido com o seguinte:

[root@trees ~]# ls -l /mnt/home/someone/something
total 4264
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 a -> /home/someone/someotherthing/a
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 b -> /home/someone/someotherthing/b
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 c -> /home/someone/someotherthing/c
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 d -> /home/someone/someotherthing/d
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 e -> /home/someone/someotherthing/e

/mnt/home/someone/something/subdir:
total 4264
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 a -> /home/someone/someotherthing/subdir/a
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 b -> /home/someone/someotherthing/subdir/b
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 c -> /home/someone/someotherthing/subdir/c
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 d -> /home/someone/someotherthing/subdir/d
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 e -> /home/someone/someotherthing/subdir/e

Eu quero um comando que encontre todos os links simbólicos e vincule novamente aos mesmos lugares, mas abaixo de /mnt/home em vez de /home

Existe tal comando?

    
por Josh 09.08.2011 / 01:04

3 respostas

51

Não há comando para redirecionar um link simbólico, tudo o que você pode fazer é removê-lo e criar outro. Supondo que você tenha utilitários GNU (por exemplo, em Linux ou Cygwin não integrado), você pode usar o -lname primary de find para corresponder links simbólicos por seu destino e readlink para ler o conteúdo do link. Não testado:

find /mnt/home/someone/something -lname '/home/someone/*' \
     -exec sh -c 'ln -snf "/mnt$(readlink "$0")" "$0"' {} \;

Seria melhor tornar esses links simbólicos relativos. Há um pequeno e conveniente utilitário chamado symlinks (originalmente de Mark Lords, agora mantido por J. Brandt Buckley), presente em muitos Linux distribuições. Antes da mudança, ou depois de restaurar os links válidos, execute symlinks -c /mnt/home/someone/something para converter todos os links simbólicos absolutos no diretório especificado em links simbólicos relativos, a menos que eles cruzem um limite do sistema de arquivos.

    
por 09.08.2011 / 02:10
13

Eu sei que isso não é exatamente o que o autor está solicitando, mas parece que eles já têm sua resposta, então estou adicionando isso para outras pessoas como eu, que se deparam com a pergunta.

O seguinte deve ajudar se uma solução mais flexível for necessária, como ter um monte de links simbólicos quebrados que podem ser corrigidos substituindo parte dos alvos do link simbólico.

por exemplo. Depois de uma mudança de nome de usuário, para substituir o nome de usuário antigo com o novo nome de usuário no destino de muitos links, após o movimento já ter sido feito. Crie um script chamado replace-simlinks mostrado abaixo:

#!/bin/bash
link=$1
# grab the target of the old link
target=$(readlink -- "$1")

# replace the first occurrence of oldusername with newusername in the target string
target=${target/oldusername/newusername}

# Test the link creation
echo ln -s -- "$target" "$link"

# If the above echo shows the correct commands are being issued, then uncomment the following lines and run the command again
#rm $link
#ln -s "$target" "$link"

e chame-o com o seguinte comando:

find /home/newusername/ -lname '/home/oldusername/*' -exec ~/bin/replace-simlinks {} \;

Espero que isso ajude alguém

edit: Obrigado ao Gilles pelo kickstart neste script e a dica sobre como usar o script symlinks para tornar os links relativos.

    
por 30.12.2011 / 17:07
3

Crie /home como um link simbólico para /mnt/home e todos os links simbólicos existentes serão válidos novamente.

    
por 30.12.2011 / 21:05