Kırık sembolik bağlantıları nasıl bulabilirim


282

Herhangi bir noktaya işaret etmeyen sembolik bağları bulmanın bir yolu var mı?

find ./ -type l

Bana tüm sembolik bağları verecek, fakat bir yere giden linkler ile gitmeyen linkler arasında bir ayrım yapmıyor.

Şu anda yapıyorum:

find ./ -type l -exec file {} \; |grep broken

Ama hangi alternatif çözümlerin mevcut olduğunu merak ediyorum.

Yanıtlar:


351

Ben kuvvetle öneririm değil kullanmak find -L görev için (açıklama için aşağıya bakınız). İşte bunu yapmanın başka yolları:

  • "Saf find" bir yöntem kullanmak istiyorsanız , bunun yerine şöyle görünmelidir:

    find . -xtype l
    

    ( xtypedereferenced bir bağlantı üzerinde yapılan bir testtir) Bu, tüm sürümlerinde bulunmayabilir find. Ancak başka seçenekler de var:

  • Ayrıca komutun test -eiçinden de yürütebilirsiniz find:

    find . -type l ! -exec test -e {} \; -print
    
  • Bazı grepnumaralar bile , (dosya isimleri de dahil olmak üzere tüm çıktı satırlarında sürtünen) soruda belirtilenden daha iyi (yani daha güvenli ) olabilir;find -L

     find . -type l -exec sh -c 'file -b "$1" | grep -q ^broken' sh {} \; -print
    

find -LAlıntılanan hüner solo ile gelen commandlinefu güzel ve hacky görünüyor, ama bir çok sahip tehlikeli hatadır : Tüm sembolik bağ izlenir. Aşağıda sunulan içerikleri içeren dizini göz önünde bulundurun:

$ 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/

Bu find -L . -type ldizinde koşarsanız, hepsi /usr/share/de aranır (ve bu gerçekten uzun sürebilir) 1 . "Giden bağlantılara bağışıklık" olan bir findkomut için kullanmayın-L .


1 Bu ufak bir rahatsızlık gibi görünebilir (bu komut, "sadece" tümünden geçmek için uzun zaman alacaktır /usr/share) - ancak daha ciddi sonuçlar doğurabilir. Örneğin, chroot ortamlarını düşünün: Ana dosya sisteminin bazı alt dizinlerinde var olabilir ve mutlak konumlara sembolik bağlantılar içerebilir. Bu bağlantılar “dış” sistem için kopmuş gibi görünebilir, çünkü chroot'a girdikten sonra sadece uygun yerlere işaret ederler. Ayrıca, bazı bootloader'ların /boot, başlangıç ​​bölümü olarak monte edildiğinde, sadece başlangıçtaki bir başlangıç ​​aşamasında anlamlı olan sembolik bağlantılar kullandığını hatırlıyorum /.

Bu yüzden, find -Lzararsız görünen bir dizinden bozuk linkleri bulmak ve silmek için bir komut kullanırsanız , sisteminizi bile bozabilirsiniz ...


11
Bence -type lgereksizdir, çünkü bağlantı dışı -xtype lolarak çalışacak -type l. Yani find -xtype lmuhtemelen tüm ihtiyaç vardır. Bu yaklaşım için teşekkürler.
Qornian

3
Bu çözümlerin tüm dosya sistemi türleri için çalışmadığını unutmayın. Örneğin, /proc/XXX/exebağlantının kopup kırılmadığını kontrol etmek için çalışmaz . Bunun için kullanın test -e "$(readlink /proc/XXX/exe)".
qwertzguy

2
@ Flimm find . -xtype l"(nihai) hedef dosyaları sembolik olan tüm bağlantı noktalarını bul" anlamına gelir. Ancak, bir sembolik bağın nihai hedefi sembolik bağ olamaz, aksi halde hala bağlantıyı takip edebiliriz ve nihai amaç değildir. Böyle bir sembolik bağ olmadığından bunları başka bir şey olarak tanımlayabiliriz, yani kırık sembolik bağlar.
zayıf

2
@ JoóÁdám "kırılması durumunda sadece sembolik bir bağlantı olabilir". "Bozuk sembolik link" veya "varolmayan dosya" ver, aşırı yükleme yerine bireysel bir tür lbenim için daha az kafa karıştırıcıdır.
Zayıf

3
Sonunda uyarı yararlıdır, ancak bunun -Lkesmek için geçerli olmadığını, bunun yerine genel olarak kırık sembolik bağları kaldırmak için (kör olarak) geçerli olduğuna dikkat edin .
Alois Mahdal,


32

Rozcietrzewiacz'ın daha önce de söylediği gibi, aramayı sembolize find -Ledilmiş dizinlere genişletmenin beklenmedik bir sonucu olabilir, bu yüzden en uygun yaklaşım bu değildir. Henüz kimsenin bahsetmediği şey bu.

find /path/to/search -xtype l

daha özlü ve mantıksal olarak özdeştir

find /path/to/search -type l -xtype l

Şimdiye kadar sunulan çözümlerin hiçbiri, başka bir kırılma türü olmayan döngüsel sembolik bağlantıları algılamayacak. bu soru taşınabilirliği ele alıyor. Özetlemek gerekirse, döngüsel bağlantılar dahil olmak üzere kırık sembolik bağlantıları bulmanın taşınabilir yolu şudur:

find /path/to/search -type l -exec test ! -e {} \; -print

Daha fazla ayrıntı için bu soruya veya ynform.org adresine bakın . Tabii ki, tüm bunlar için kesin kaynak buluntular belgeseldir .


1
Kısa, bilinç ve find -Ltuzak yanı sıra döngüsel bağlantılar giderir . +1
Flimm

Güzel. Sonuncusu MacOSX üzerinde de çalışıyor, oysa @ rozcietrzewiacz'ın cevabı yoktu.
neu242,

1
@ çünkü muhtemelen neu242 -xtypePOSIX'deki belirtilen ve bakarsak aslında değil find(1)MacOS yakaladığı -typeama değil -xtype .
Pryftan

7

-LBayrakları emrinize eklemeniz, grepten kurtulmanıza izin verecek:

$ find -L . -type l

http://www.commandlinefu.com/commands/view/8260/find-broken-symlinks

adamdan:

 -L      Cause the file information and file type (see stat(2)) returned 
         for each symbolic link to be those of the file referenced by the
         link, not the link itself. If the referenced file does not exist,
         the file information and type will be for the link itself.

19
İlk başta bunu aştım, ama sonra ne kadar tehlikeli olabileceğini anladım . Kullanmadan önce, lütfen cevabımı ara !
rozcietrzewiacz

6

Bağlantının kopmuş ya da döngüsel olup olmadığı konusunda farklı bir davranışa ihtiyaç duyarsanız, şunu bulmak için% Y'yi de kullanabilirsiniz:

$ touch a
$ ln -s a b  # link to existing target
$ ln -s c d  # link to non-existing target
$ ln -s e e  # link to itself
$ find . -type l -exec test ! -e {} \; -printf '%Y %p\n' \
   | while read type link; do
         case "$type" in
         N) echo "do something with broken link $link" ;;
         L) echo "do something with cyclic link $link" ;;
         esac
      done
do something with broken link ./d
do something with cyclic link ./e

Bu örnek bu yazıdan kopyalandı (site silindi) .

Referans


Kimin olanlar için Henüz başka steno findkomutu desteklemeyen xtypebu elde edilebilir: find . type l -printf "%Y %p\n" | grep -w '^N'. Andy beni senaryosunda aynı (temel) fikirle yendiğinde, ayrı bir cevap olarak yazmak konusunda isteksizdim. :)
syntaxerror

2

Bunu durumum için kullanıyorum ve kırık semboliklere bakmak için dizini bildiğim için gayet iyi çalışıyor:

find -L $path -maxdepth 1 -type l

ve klasörüm bir bağlantı içeriyor, /usr/shareancak onu geçmiyor. Cihazlar arası bağlantılar ve chroots vb. İçin geçerli olanlar hala bir sorun teşkil ediyor, ancak benim kullanımım için bu yeterli.


2

OP versiyonundaki bir değişiklik olan basit, basit cevap yok. Bazen, yazması veya hatırlaması kolay bir şey istersiniz:

find . | xargs file | grep -i "broken symbolic link"

1

find -L . -type l |xargs symlinks Bağlantının, bulunan dosya başına esasında olup olmadığına dair size bilgi verecektir.


1

Bu, geçerli dizindeki bozuk işaretlerin adlarını yazdıracaktır.

for l in $(find . -type l); do cd $(dirname $l); if [ ! -e "$(readlink $(basename $l))" ]; then echo $l; fi; cd - > /dev/null; done

Bash'de çalışıyor. Diğer mermileri bilmiyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.