จะแสดงรายการเชนลิงก์สัญลักษณ์อย่างไร


36

รับตัวอย่างนี้:

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

หากฉันดำเนินการ:

ls -l d

มันจะแสดง:

d -> c

มีวิธีการlsหรือคำสั่ง linux อื่น ๆ ที่จะแสดงd -> c -> b -> aแทน?


ฉันข้ามโพสต์สิ่งนี้เป็นstackoverflow.com/questions/2320277/… ฉันหวังว่าคุณจะไม่รังเกียจ
พอล

คำตอบ:


65

เพียงใช้namei:

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

5
TIL นี่เป็นคำสั่งที่ยอดเยี่ยม upvotes
Tom O'Connor

นี่ควรเป็นคำตอบที่ได้รับการยอมรับเพราะมันแสดงให้เห็นถึงห่วงโซ่การเชื่อมโยงทั้งหมดตามที่ร้องขอใน op lsเพิ่มเติมก็สามารถนำมาใช้เพื่อแสดงรายการสารบบทั้งหมดจะคล้ายกัน ขอบคุณ!
phobic

อันที่จริงแล้วการมาเยือนโพสต์นี้อีกครั้งและ namei เป็นคำสั่งที่ยอดเยี่ยม!
Kalecser

ใช้กับคำสั่ง "ซึ่ง" เพื่อค้นหาการใช้งานจริงของโปรแกรม: $ namei `ซึ่ง java`
pdem

18

readlink -e <link>

readlink [ตัวเลือก] ... ไฟล์

  • -e, - สามารถ
    กำหนดมาตรฐานให้เป็นมาตรฐานได้โดยปฏิบัติตามทุก symlink ในทุกองค์ประกอบของชื่อที่กำหนดซ้ำส่วนประกอบทั้งหมดจะต้องมีอยู่
$ 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

หมายเหตุ: readlink a โดยตัวของมันเองจะคืนค่า b

หมายเหตุ # 2: ร่วมกับ find -l ยูทิลิตี้ในการแสดงรายการเชนสามารถเขียนได้อย่างง่ายดายในภาษา Perl แต่ต้องมีความฉลาดพอที่จะตรวจจับลูปได้

readlink จะไม่แสดงผลใด ๆ หากคุณมีลูป ฉันคิดว่ามันดีไปกว่าติดอยู่

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: brew install coreutilsและgreadlink -e <link>
Jose Alban

3

นี่คือฟังก์ชั่นวนซ้ำใน 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; }

ในหลายบรรทัด:

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
}

ตัวอย่าง:

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

มันต้องการstat(1)ซึ่งอาจไม่ปรากฏในบางระบบ

มันจะล้มเหลวหากชื่อมี backticks, เครื่องหมายคำพูดเดี่ยวหรือ "->" มันติดอยู่ในลูปที่มีลูป symlink (ซึ่งสามารถแก้ไขได้โดยใช้อาเรย์แบบเชื่อมโยงใน Bash 4) มันส่งออกตัวแปรที่เรียกว่า "โซ่" โดยไม่คำนึงว่ามันมีการใช้งานแล้ว

อาจมีปัญหาอื่น ๆ

แก้ไข:

แก้ไขปัญหาเกี่ยวกับ symlink ที่เกี่ยวข้อง บางรุ่นยังไม่ทำงาน แต่รุ่นด้านล่างไม่ต้องการเป้าหมายของลิงก์ที่มีอยู่

เพิ่มรุ่นที่ใช้ readlink:

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
}

ฉันทดสอบสคริปต์ของคุณแล้วและใช้งานได้จริง แต่ฉันชอบบางสิ่งที่ง่ายกว่าดังนั้นฉันจึงยอมรับคำตอบอื่น ๆ แม้ว่าจะไม่สมบูรณ์
Kalecser

1
สคริปต์ที่ดี บางครั้งฉันต้องการที่จะเห็นห่วงโซ่ทั้งหมดและreadlinkดูเหมือนจะไม่แสดงให้เห็นว่า Java บน Ubuntu คือ:/usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java
Stefan Lasiewski

0

คุณสามารถประมวลผลเอาต์พุตของ namei ด้วยสิ่งที่ชอบawkหรือgrepเพื่อให้ได้บรรทัดที่คุณต้องการ:

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

หรือ

namei d | egrep -e "->"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.