Converter links simbólicos em links físicos

25

Gostaria de converter recursivamente links flexíveis em links físicos em um diretório. Eu tentei algo como isto:

for f in *; do (mv $f{,~} && ln $(readlink $f~) && rm $f~) done

... mas tem dois grandes problemas:

  • não recursivo
  • pega arquivos que não são links simbólicos

Seria bom, de alguma forma, alimentar a linha acima find -type l, mas não sei como fazer isso.

Attila O.
fonte
11
Veja também [esta discussão] [1] ( cp -aH). [1]: unix.stackexchange.com/questions/94185/…
Michael Shigorin 23/04

Respostas:

34

Este comando deve funcionar:

find -type l -exec bash -c 'ln -f "$(readlink -m "$0")" "$0"' {} \;

Como funciona:

  • find -type l localiza todos os links no diretório atual.

  • -exec bash -c '...' {} \;chama bash para executar ....

    Ele passa {}- o nome do link que está sendo processado atualmente - como um argumento, ao qual o bash pode acessar $0.

  • readlink -m "$0" retorna o caminho absoluto do destino do link simbólico.

  • ln -f "$(readlink -m "$0")" "$0"sobrescreve ( -f) o link simbólico $0com um link físico para seu destino.

Se o link não puder ser convertido por algum motivo, ele permanecerá intocado e o ln imprimirá uma mensagem de erro.

Dennis
fonte
Em relação ao último parágrafo, não seria suficiente especificar caminhos absolutos para bashe ln?
Daniel Beck
2
Meu problema era que o readlink retorna um caminho relativo por padrão, mas a -eopção corrige isso.
Dennis
Qual seria o comando para o OSX?
Igor Markelov
@IgorMarkelov Sinto muito, mas não tenho idéia quando se trata de OSX.
Dennis
11
Em um Mac, é: brew install coreutilse find * -type l -exec bash -c 'ln -f "$(greadlink -m "$0")" "$0"' {} \;.
Igor Markelov