A renomeação de arquivos funciona, mas os soft links apontam para os nomes antigos. Como posso consertar isso?

4

Por exemplo, estou renomeando muitos arquivos dentro de uma árvore assim:

[bash]$ for file in 'find . -name "*gsf*"'; do 'mv $file ${file/gsf/msf}'; done

Isso renomeia todas as instâncias de "gsf" em nomes de arquivos que correspondem a gsf para "msf", mas os softlinks continuam apontando para arquivos agora inexistentes contendo "gsf".

Por exemplo, é isso que acontece depois da renomeação:

lrwxrwxrwx 1 trusktr users     20 Apr 25 14:39 libmsf-1.so -> libgsf-1.so.114.0.23
lrwxrwxrwx 1 trusktr users     20 Apr 25 14:39 libmsf-1.so.114 -> libgsf-1.so.114.0.23
-rwxr-xr-x 1 trusktr users 265584 Apr 21 04:41 libmsf-1.so.114.0.23

Como você pode ver, os links apontam para libgsf-1.so.114.0.23 , que não existe mais, porque foi renomeado para libmsf-1.so.114.0.23 .

O que posso fazer para que a renomeação também aconteça aos ponteiros do link de software?

    
por trusktr 26.04.2012 / 01:23

5 respostas

1

Com base nas respostas do @ C2H5OH e @user1277476, encontrei uma solução:

$ for file in 'find . -type l'; do link=$(readlink $file); ln -sfT ${link//gsf/msf} $file; done
    
por 26.04.2012 / 05:19
3

Nada; isso é o que faz deles links simbólicos, você precisa lidar com eles sozinho. Os links físicos referenciam o nó de índice real ("inode") no sistema de arquivos e, portanto, permanecem válidos; é exatamente por isso que você usaria hard links em vez de links simbólicos nesse caso.

    
por 26.04.2012 / 01:26
3

Além da explicação técnica, já respondida. Você pode alterar para onde os links simbólicos apontam:

  1. Encontre-os com find . -type l
  2. Altere o alvo com ln -sfT target link_name

As opções -sfT devem ser especificadas para reenviar links simbólicos sem surpresas.

    
por 26.04.2012 / 01:30
2

find e ln são bons.
readlink também é bom.

    
por 26.04.2012 / 02:21
1

Desde que eu não posso adicionar um comentário, aqui está uma versão que não invoca um shell para encontrar links, evitando assim sobrecarga adicional devido a fork () e outros syscalls

for file in $(find . -type l); do 
    link=$(readlink $file); 
    ln -sfT ${link//gsf/msf} $file; 
done

Isso é baseado na resposta @trusktr

    
por 24.12.2017 / 04:58