encontre todos os links simbólicos em uma árvore de diretórios apontando para fora dessa árvore

8

Eu freqüentemente movo árvores de diretório para outros locais ou copio seus tarballs para outras máquinas, e gostaria de ter um método para verificar se algum link simbólico em uma árvore de diretórios A aponta para locais fora de A, pois eles serão quebrados no arquivo movido / copiado diretório.

Marcus Junius Brutus
fonte

Respostas:

7

Você quer um programa chamado realpath, usado em conjunto com find.

Por exemplo:

find . -type l -exec realpath {} \; | grep -v "^$(pwd)"
bahamat
fonte
1
O encantamento fornecido apenas informa o local de destino incorreto, não o link simbólico que aponta para ele. Como tal, removi minha aceitação. Por favor, veja minha "resposta" abaixo: unix.stackexchange.com/a/308899/24044 e se você estiver feliz com ela (ou melhorá-la), excluirei minha "resposta" e aceito sua pergunta novamente.
Marcus Júnio Bruto
2

Use bindfs para criar outra visualização dessa árvore de diretórios.

mkdir /tmp/view
bindfs /some/directory /tmp/view

Em seguida, use o utilitário symlinks (enviado por muitas distribuições ou compilá-lo da fonte ) para detectar links entre sistemas de arquivos.

symlinks -r /tmp/view | sed -n 's/^\(absolute\|other_fs\): //p'

(Observe que a análise da saída pressupõe que seus links simbólicos e seus destinos não contêm novas linhas, nem os caminhos para links simbólicos contêm a substring  -> .) Esse mesmo utilitário também pode converter links simbólicos absolutos em relativos (mas você deseja fazer isso em a localização original).

Gilles 'SO- parar de ser mau'
fonte
2

Com zsh:

cd -P -- "$dir"
for i (**/*(ND@)) [[ $i:A = $PWD/* ]] || [[ $i:A = $PWD ]] || print -r -- "$i => $i:A"

Agora, se o diretório é /fooe você tem /foo/barum link simbólico /foo/baz, esse é um link cujo destino está em / foo, mas uma vez movido, o link ainda será quebrado, portanto, convém também associar links simbólicos a caminhos absolutos.

Mas mesmo assim, um bar => ../foo/bazin /fooseria um problema (falso negativo), assim como um a => bwhere bé um link simbólico fora da árvore (falso positivo, dependendo de como você deseja vê-lo)

Stéphane Chazelas
fonte
2

Eu tive que ajustar um pouco a resposta dada por @bahamat para fazê-lo funcionar.

A versão fornecida simplesmente informava o local absoluto ofensivo, mas não o link simbólico que aponta para ele.

Aqui está o que eu usei (tenho certeza que pode ser melhorado):

for f in $(find . -type l ); do echo -n $(realpath $f) && echo -n "|" && echo $f ; done | grep -v "^$(pwd)" | cut -d \| -f 2 
Marcus Junius Brutus
fonte
Eu encontrei este para ser o script mais útil: for f in $(find . -type l); do echo $(realpath -m -q $f) '<-' $f; done | grep-v "^$(pwd)"(mais notavelmente -me -qque filtra links quebrados e não externos)
Adam Lindberg
1

Provas de coreutils GNU realpath, que resolvem links simbólicos. Com isso, você pode comparar o destino de cada link simbólico com o diretório de trabalho atual com algo como:

#!/bin/bash

find . | while read filename
do
  if realpath $filename | grep -E "^$PWD" > /dev/null
  then
    echo 'this file is safe'
  else
    echo 'this file links externally'
  fi
done
dois pontos
fonte
Vários problemas: não -type l, nenhuma -ropção de read, não IFS higienizado para read, $filenamenão cotados, $PWDtratado como uma expressão regular, caminhos com caracteres de nova linha não contabilizados, /foobarseriam combinados para $PWD== "/ foo"
Stéphane Chazelas