Sembolik bağlantı zincirleri nasıl listelenir?


Yanıtlar:


65

Sadece kullan namei:

$ namei d
f: d
 l d -> c
   l c -> b
     l b -> a
       d a

5
TIL. Bu harika bir komut. oyları
Tom O'Connor

Operasyonda talep edilen bağlantıların tam zincirini gösterdiği için bu kabul edilen cevap olmalıdır. Ayrıca, benzer bir dizinin tamamını listelemek için kullanılabilir ls. Teşekkürler!
fobik

Nitekim, bu yazı tekrar ziyaret ediyordu ve namei harika bir komut!
Kalecser

Bir programın gerçek kullanımını bulmak için "which" komutunu kullanın: $ namei `hangi java`
pdem

18

readlink -e <link>

readlink [SEÇENEK] ... DOSYA

  • -e, - canonicalize-var
    verilen adın her bileşenindeki her sembolik bağlantıyı tekrarlı bir şekilde izleyerek kanonikleştirin , tüm bileşenler mevcut olmalıdır
$ mkdir testlink
$ cd testlink
pjb@pjb-desktop:~/testlink$ ln -s c b
pjb@pjb-desktop:~/testlink$ ln -s b a
pjb@pjb-desktop:~/testlink$ ls -l 
total 0
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 a -> b
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 b -> c
pjb@pjb-desktop:~/testlink$ echo foo > c
pjb@pjb-desktop:~/testlink$ cat a
foo
pjb@pjb-desktop:~/testlink$ readlink -e a
/home/pjb/testlink/c

not: readlink a kendi kendine b döndürür

not # 2: find -l ile birlikte, zincirleri listelemek için bir yardımcı program kolayca perl olarak yazılabilir, ancak döngüleri algılamak için yeterince akıllı olması gerekir

Eğer bir döngü varsa readlink hiçbir şey çıkarmaz. Sanırım sıkışmaktan iyidir, sanırım.

pjb@pjb-desktop:~/testlink$ ln -sf a c
pjb@pjb-desktop:~/testlink$ ls -l 
total 0
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 a -> b
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 b -> c
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 09:03 c -> a
pjb@pjb-desktop:~/testlink$ readlink -e a
pjb@pjb-desktop:~/testlink$ # (note: no output)

OS X'te: brew install coreutilsvegreadlink -e <link>
Jose Alban

3

İşte Bash'te özyinelemeli bir işlev:

chain() { export chain; local link target; if [[ -z $chain ]]; then chain="$1"; fi; link=$(stat --printf=%N $1); while [[ $link =~ \-\> ]]; do target="${link##*\`}"; target="${target%\'}"; chain+=" -> $target"; chain "$target"; return; done; echo "$chain"; unset chain; }

Birden fazla satırda:

chain() {
    export chain
    local link target
    if [[ -z $chain ]]
    then
        chain="$1"
    fi
    link=$(stat --printf=%N "$1")
    while [[ $link =~ \-\> ]]
    do
        target="${link##*\`}"
        target="${target%\'}"
        chain+=" -> $target"
        if [[ ! $target =~ / && $1 =~ / ]]
        then
            target="${1%/*}/$target"
        fi
        chain "$target"
        return
    done
    echo "$chain"
    unset chain
}

Örnekler:

$ chain d
d -> c -> b -> a
$ chain c
c -> b -> a
$ chain a
a

stat(1)Bazı sistemlerde bulunmayacak olanı gerektirir .

Eğer isimler backticks, tek tırnak işareti veya "->" içeriyorsa başarısız olur. Sembolik bağlantı halkaları olan bir döngüde sıkışıp kalıyor (Bash 4'te bir ilişkisel dizi kullanılarak çözülebilir). Zaten kullanımda olup olmadığına bakılmaksızın "zincir" adlı bir değişken verir.

Bununla ilgili başka sorunlar olabilir.

Düzenle:

Bazı göreceli sembolik bağlantılarla ilgili bir sorun düzeltildi. Bazıları hala çalışmıyor, ancak aşağıdaki sürüm, bağlantının hedefinin var olmasını gerektirmiyor.

Readlink kullanan bir sürüm eklendi:

chain ()
{
    export chain;
    local target;
    if [[ -z $chain ]]; then
        chain="$1";
    fi;
    target=$(readlink "$1");
    while [[ $target ]]; do
        chain+=" -> $target";
        if [[ ! $target =~ / && $1 =~ / ]]
        then
            target="${1%/*}/$target"
        fi
        chain "$target";
        return;
    done;
    echo "$chain";
    unset chain
}

Senaryonuzu test ettim ve gerçekten işe yarıyor ama daha basit bir şey tercih ediyorum, bu yüzden eksik olsa bile diğer cevabı kabul ettim.
Kalecser

1
Güzel senaryo. Bazen tüm zinciri görmek istiyorum, ve readlinkbunu gösterecek gibi görünmüyor. Ubuntu'da Java:/usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java
Stefan Lasiewski

0

Sadece namei'nin çıktısını şunun gibi bir şeyle işlemden geçirebilir awkya da grepistediğiniz çizgileri elde edebilirsiniz:

namei d | awk '$1=="l"'

veya

namei d | egrep -e "->"
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.