รับตัวอย่างนี้:
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
แทน?
รับตัวอย่างนี้:
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
แทน?
คำตอบ:
เพียงใช้namei
:
$ namei d
f: d
l d -> c
l c -> b
l b -> a
d a
ls
เพิ่มเติมก็สามารถนำมาใช้เพื่อแสดงรายการสารบบทั้งหมดจะคล้ายกัน ขอบคุณ!
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)
brew install coreutils
และgreadlink -e <link>
นี่คือฟังก์ชั่นวนซ้ำใน 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
}
readlink
ดูเหมือนจะไม่แสดงให้เห็นว่า Java บน Ubuntu คือ:/usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java
คุณสามารถประมวลผลเอาต์พุตของ namei ด้วยสิ่งที่ชอบawk
หรือgrep
เพื่อให้ได้บรรทัดที่คุณต้องการ:
namei d | awk '$1=="l"'
หรือ
namei d | egrep -e "->"