Bagaimana cara mendaftar rantai tautan simbolis?

36

Diberikan contoh ini:

mkdir a
ln -s a b
ln -s b c
ln -s c d

Jika saya menjalankan:

ls -l d

Ini akan menunjukkan:

d -> c

Apakah ada cara untuk lsatau perintah linux lainnya untuk ditampilkan d -> c -> b -> a?

Kalecser
sumber
Saya mengirim ini sebagai stackoverflow.com/questions/2320277/… Saya harap Anda tidak keberatan.
Paul

Jawaban:

65

Cukup gunakan namei:

$ namei d
f: d
 l d -> c
   l c -> b
     l b -> a
       d a
Mike
sumber
5
TIL. Ini adalah perintah yang keren . upvotes
Tom O'Connor
Ini harus menjadi jawaban yang diterima, karena ini menunjukkan rantai tautan lengkap seperti yang diminta dalam op. Selanjutnya dapat digunakan untuk mendaftar seluruh direktori yang mirip dengan ls. Terima kasih!
fobia
Memang, sedang meninjau kembali posting ini dan namei adalah perintah yang luar biasa!
Kalecser
gunakan dengan perintah "which" untuk menemukan penggunaan aktual suatu program: $ namei `which java`
pdem
18

readlink -e <link>

readlink [OPTION] ... FILE

  • -e, --canonicalize-
    canonicalize yang ada dengan mengikuti setiap symlink di setiap komponen nama yang diberikan secara rekursif, semua komponen harus ada
$ 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

catatan: readlink a dengan sendirinya mengembalikan b

Catatan # 2: bersama dengan -l, sebuah utilitas untuk membuat daftar rantai dapat dengan mudah ditulis dalam perl, tetapi juga harus cukup pintar untuk mendeteksi loop

readlink tidak akan menghasilkan apa pun jika Anda memiliki loop. Ini lebih baik daripada terjebak, saya kira.

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)
Paul
sumber
Pada OS X: brew install coreutilsdangreadlink -e <link>
Jose Alban
3

Berikut adalah fungsi rekursif di Bash:

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; }

Pada banyak baris:

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
}

Contoh:

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

Ini membutuhkan stat(1)yang mungkin tidak ada pada beberapa sistem.

Ini akan gagal jika nama berisi backticks, tanda kutip tunggal, atau "->". Terjebak dalam satu lingkaran dengan loop symlink (ini bisa diselesaikan menggunakan array asosiatif dalam Bash 4). Ini mengekspor variabel yang disebut "rantai" tanpa memperhatikan apakah itu sudah digunakan.

Mungkin ada masalah lain dengan itu.

Edit:

Memperbaiki masalah dengan beberapa symlink relatif. Beberapa masih tidak berfungsi, tetapi versi di bawah ini tidak memerlukan target tautan yang ada.

Menambahkan versi yang menggunakan tautan baca:

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
}
Dijeda sampai pemberitahuan lebih lanjut.
sumber
Saya telah menguji skrip Anda dan itu benar-benar berfungsi tetapi saya lebih suka sesuatu yang lebih sederhana sehingga saya menerima jawaban yang lain meskipun tidak lengkap.
Kalecser
1
Naskah yang bagus. Terkadang saya ingin melihat seluruh rantai, dan readlinksepertinya tidak menunjukkan itu. Java pada Ubuntu adalah:/usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java
Stefan Lasiewski
0

Anda bisa memposting proses namei dengan sesuatu seperti awkatau grepuntuk mendapatkan baris yang Anda inginkan:

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

atau

namei d | egrep -e "->"
Tony
sumber