ค้นหาจุดหมายปลายทางของ symlink เท่านั้น


50

เพื่อใช้ในเชลล์สคริปต์ฉันกำลังมองหา commandline-way เพื่อรับปลายทางของลิงก์สัญลักษณ์ ที่ใกล้เคียงที่สุดที่ผมได้มาเพื่อให้ห่างไกลซึ่งเอาท์พุทstat -N src src -> dstแน่นอนว่าฉันสามารถแยกเอาท์พุทและรับได้dstแต่ฉันสงสัยว่ามีวิธีการรับปลายทางโดยตรงหรือไม่

คำตอบ:


61

อีกตัวเลือกหนึ่งคือใช้คำสั่งที่ออกแบบมาโดยเฉพาะreadlinkหากมี

เช่น

$ readlink -f `command -v php`
/usr/bin/php7.1

21
ใช้readlink -fถ้าคุณต้องการที่จะรู้ว่าที่ผ่านมาเป้าหมาย symlink และไม่เพียง แต่ต่อไปอย่างใดอย่างหนึ่ง
scai

จุดดี! ลืมสิ่งนั้น
nikitautiu

11
โปรดทราบว่า-fเป็นส่วนขยายที่ไม่ได้พกพาไป readlinkGNU
บาฮามาต

2
เมื่อใดที่ readlink จะไม่พร้อมใช้งาน ขอบคุณ
tommy.carstensen

2
@ tommy.carstensen readlink (1) ถูกเพิ่มเข้าไปใน coreutils ของ GNU ในปี 2003 ดังนั้นวันนี้คุณอาจขึ้นอยู่กับมันในทุกระบบที่ใช้ coreutils (เทียบกับgit.savannah.gnu.org/cgit/coreutils.git/commit/src/ … )
Josip Rodin

15

บน Mac OS X และ FreeBSD / NetBSD / ฯลฯ มันเป็น:

stat -f %Y <filename>

โดยทั่วไปฉันคิดว่าคำตอบคือ (stat --printf =% N ใช้คำพูดแปลก ๆ ):

ls -l b | sed -e 's/.* -> //'

ตัวอย่าง:

# ln -s a b
# stat -f %Y b
a

วิธีอื่นคือ:

# find b -maxdepth 0 -printf %l
a#

บรรทัดสุดท้ายมีการพันกันเนื่องจากไม่มีบรรทัดใหม่ แต่ก็ใช้ได้ถ้าคุณต้องการผลลัพธ์ในตัวแปรเช่นนั้น

# f=$(find b -maxdepth 0 -printf %l)
# echo $f
a

-maxdepthเป็นสิ่งจำเป็นเพื่อป้องกันไม่ให้findจากมากไปหาน้อยลงในไดเรกทอรีถ้าbเกิดขึ้นจะเป็นไดเรกทอรี


ฉันขาดมันไปทั้งหมดstat --printf='%N\n'คือสิ่งที่ฉันต้องการคำพูดแปลก ๆ ไม่รบกวนฉันคำพูดเดิม ๆ ของพวกเขา rm and ln
โต้ตอบ

นี้เห็นได้ชัดว่าไม่ได้เป็นแบบพกพาเพราะบน Linux สถิติ coreutils GNU (1) มีพารามิเตอร์ที่แตกต่างกันและพิมพ์ออกlink -> destในการส่งออก ควรตรวจสอบวิธีการค้นหา (1) ว่ามี GNU findutils หรือไม่ ...
Josip Rodin

โปรดอย่าลืมที่จะพูดการขยายตัวแปรของคุณecho $fแน่นอนไม่ได้ผลิตสิ่งที่คุณคาดหวังเมื่อ symlink ชี้ไปที่/*(ใช่มันเป็นไปได้)
Camusensei


1

แบบพกพา: ไม่มีโชคยกเว้นการใช้ฮิวริสติกเพื่อแยกเอาต์พุต ls -l หรือใช้ perl -le 'print readlink("some-file")'

บางระบบมีreadlinkคำสั่งบางระบบมี-fตัวเลือกเพื่อรับพา ธ สัมบูรณ์

มีการนำไปใช้งานต่าง ๆ ของstatคำสั่งเป็นตัวหุ้มสำหรับการเรียกstat/ lstatsystem GNU หนึ่งไม่มีประโยชน์ในเรื่องนั้น แต่สิ่งที่มีในตัวของ zsh นั้นมีมากกว่า:

zmodload zsh/stat
stat +link the-link

ยังคงมี zsh คุณสามารถรับพา ธ สัมบูรณ์ของไฟล์ (ลบคอมโพเนนต์ symlink ทั้งหมด) ด้วยโมดิ:Aฟายเออร์ (ใช้กับการขยายตัวแปรการขยายประวัติและการวนซ้ำ:

~$ gstat -c %N b
`b' -> `a'
~$ var=b
~$ echo $var:A
/home/me/a
~$ echo b(:A)
/home/me/a
~$ echo ?(@:A)
/home/me/a

1

ในระบบที่ฉันไม่มีreadlinkหรือstatคำสั่ง แต่ฉันมี Python 2.x ฉันใช้สคริปต์สั้น ๆ :

#!/usr/bin/env python

import os, sys

if __name__ == "__main__":
    src = sys.argv[1]
    target = os.readlink(src)
    if not os.path.isabs(target):
            target = os.path.abspath(os.path.join(os.path.dirname(src), target))
    print target

โปรดทราบว่าไม่เหมือนกับreadlink -fสิ่งนี้อาจตาม symlink ในระดับเดียว


1

พกพาเพียวเรียลพา ธ

bash_realpath() {
  # print the resolved path
  # @params
  # 1: the path to resolve
  # @return
  # &1: the resolved link path

  local path="${1}"
  while [[ -L ${path} && "$(ls -l "${path}")" =~ -\>\ (.*) ]]
  do
    path="${BASH_REMATCH[1]}"
  done
  echo "${path}"
}

0

realpathคำสั่งของcoreutilsแพคเกจ

ลิงก์ในreadlinkหน้าคู่มือของคำสั่ง


ตัวอย่างเช่น:

realpath /bin/python

เอาท์พุท

/usr/bin/python2.7

บนเครื่องของฉัน

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