
Existe uma maneira de encontrar todos os links simbólicos que não apontam para lugar nenhum?
find ./ -type l
me dará todos os links simbólicos, mas não fará distinção entre links que vão para algum lugar e links que não vão.
Atualmente estou fazendo:
find ./ -type l -exec file {} \; | grep broken
Mas estou me perguntando quais soluções alternativas existem.
Responder1
Eu sugiro fortementenãousar find -L
para a tarefa (veja a explicação abaixo). Aqui estão algumas outras maneiras de fazer isso:
Se você quiser usar um
find
método "puro", e assumindo a implementação GNU defind
, ele deve ficar assim:find . -xtype l
(
xtype
é um teste realizado em um link desreferenciado)de forma portável (embora menos eficiente), você também pode executar
test -e
a partir dofind
comando:find . -type l ! -exec test -e {} \; -print
Até mesmo algum
grep
truque poderia ser melhor (ou seja,mais segura) do quefind -L
, mas não exatamente como apresentado na pergunta (que greps em linhas de saída inteiras, incluindo nomes de arquivos):find . -type l -exec sh -c 'file -b "$1" | grep -q "^broken"' sh {} \; -print
O find -L
truque citadopor solodelinha de comandofuparece legal e hacky, mas tem um muitoarmadilha perigosa: Todos os links simbólicos são seguidos. Considere diretório com o conteúdo apresentado abaixo:
$ ls -l
total 0
lrwxrwxrwx 1 michal users 6 May 15 08:12 link_1 -> nonexistent1
lrwxrwxrwx 1 michal users 6 May 15 08:13 link_2 -> nonexistent2
lrwxrwxrwx 1 michal users 6 May 15 08:13 link_3 -> nonexistent3
lrwxrwxrwx 1 michal users 6 May 15 08:13 link_4 -> nonexistent4
lrwxrwxrwx 1 michal users 11 May 15 08:20 link_out -> /usr/share/
Se você executar find -L . -type l
nesse diretório, tudo /usr/share/
também será pesquisado (e isso pode demorar muito) 1 .Para um find
comando "imune a links de saída", não use-L
.
1 Isso pode parecer um pequeno inconveniente (o comando “simplesmente” demorará muito para percorrer todos os /usr/share
) – mas pode ter consequências mais graves. Por exemplo, considere ambientes chroot: eles podem existir em algum subdiretório do sistema de arquivos principal e conter links simbólicos para locais absolutos. Esses links podem parecer quebrados para o sistema "externo", porque eles só apontam para os locais apropriados depois que você entra no chroot. Lembro-me também que alguns gerenciadores de inicialização usavam links simbólicos /boot
que só faziam sentido na fase inicial de inicialização, quando a partição de inicialização era montada como /
.
Portanto, se você usar um find -L
comando para localizar e excluir links simbólicos quebrados de algum diretório de aparência inofensiva, poderá até quebrar seu sistema...
Responder2
Como rozcietrzewiacz já comentou, find -L
pode ter consequências inesperadas ao expandir a pesquisa em diretórios com links simbólicos, portanto não é a abordagem ideal. O que ninguém mencionou ainda é que
find /path/to/search -xtype l
é o comando mais conciso e logicamente idêntico para
find /path/to/search -type l -xtype l
Nenhuma das soluções apresentadas até agora detectará links simbólicos cíclicos, que é outro tipo de quebra. essa questãoaborda a portabilidade. Resumindo, a maneira portátil de encontrar links simbólicos quebrados, incluindo links cíclicos, é:
find /path/to/search -type l -exec test ! -e {} \; -print
Para mais detalhes, consulteessa questãoouynform.org. É claro que a fonte definitiva de tudo isso é odocumentação do findutils.
Responder3
O symlinks
comando dehttp://www.ibiblio.org/pub/Linux/utils/file/symlinks-1.4.tar.gzpode ser usado para identificar links simbólicos com uma variedade de características. Por exemplo:
$ rm a
$ ln -s a b
$ symlinks .
dangling: /tmp/b -> a
Responder4
Acredito que adicionar o -L
sinalizador ao seu comando permitirá que você se livre de grep
:
$ find -L . -type l
http://www.commandlinefu.com/commands/view/8260/find-broken-symlinks
do manual:
-L
Faça com que as informações e o tipo de arquivo (consulte
stat
(2)) retornados para cada link simbólico sejam aqueles do arquivo referenciado pelo link, não o link em si. Se o arquivo referenciado não existir, as informações e o tipo do arquivo serão do próprio link.