วิธีรับพา ธ แบบเต็มของไฟล์ต้นฉบับของลิงก์สัญลักษณ์แบบนุ่ม?


99

ฉันต้องการscpไฟล์ไปยังเซิร์ฟเวอร์ ไฟล์นี้เป็นลิงก์สัญลักษณ์และจริงๆแล้วสิ่งที่ฉันต้องการทำคือคัดลอกไฟล์ต้นฉบับ อย่างไรก็ตามฉันไม่ต้องการติดตามเส้นทางของไฟล์ต้นฉบับด้วยตนเองเพราะสามารถเปลี่ยนได้ ถ้าฉันสามารถหาพา ธ สัมบูรณ์ของไฟล์ต้นฉบับได้ฉันsepก็ทำได้ ฉันจะหาเส้นทางได้อย่างไร


2
scpเวอร์ชันส่วนใหญ่จะติดตาม symlink ตามค่าเริ่มต้นใช่ไหม คุณควรตรวจสอบและช่วยตัวเองบ้าง
jw013

@ jw103 ขอบคุณที่บอกให้ฉันรู้ ฉันไม่รู้ :)
Eonil

2
หมายเหตุ: scp -rบังคับให้ติดตาม symlink
Eonil

คำตอบ:


129

ลองบรรทัดนี้:

readlink -f `which command`

หากcommandอยู่ใน$PATHตัวแปรของคุณมิฉะนั้นคุณต้องระบุเส้นทางที่คุณรู้


12
-fจะคืนค่าพา ธ ไปยังเป้าหมายสุดท้ายที่ไม่มีอยู่จริงตราบใดที่เป้าหมายลิงก์กลางมีอยู่ ... ใช้-eเพื่อหลีกเลี่ยงปัญหานี้คือ -eจะส่งคืนค่าว่างหากเป้าหมายสุดท้ายไม่มีอยู่
Peter.O

10
-fข้อผิดพลาดกับreadlink: illegal option -- fใน OSX การลบมันทำงานได้ดี
Heath Borders

2
@HeathBorders สำหรับ OSX หากคุณติดตั้ง homebrew coreutils คุณสามารถใช้greadlinkแทนได้
Adam Gent

23

ภายใต้ Linux ให้readlinkอ่านเนื้อหาของ symlink และreadlink -fติดตามsymlink ไปยัง symlink ไปยัง symlink เป็นต้นจนกระทั่งพบสิ่งที่ไม่ใช่ symlink

ซึ่งไม่จำเป็นสำหรับ scp แม้ว่า: scp จะติดตาม symlink เสมอ (มันจะคัดลอกเนื้อหาไฟล์เสมอโดยไม่สนใจข้อมูลเมตายกเว้นว่าจะ-pเก็บรักษาเวลาและโหมดไฟล์เมื่อทำได้)

หากคุณพบว่าตัวเองผิดหวังกับข้อมูลเมตาของ scp ที่สามารถและไม่สามารถรักษาไว้ได้ฉันขอแนะนำให้ใช้ rsync ไม่มีตัวเลือก rsync คัดลอกเนื้อหาไฟล์โดยไม่สนใจเมทาดาทา ตัวเลือกที่ใช้กันทั่วไปจะ-aรักษาข้อมูลเมตาของความหลากหลายในสวน (เวลาลิงก์สัญลักษณ์สิทธิ์และความเป็นเจ้าของ) และมีตัวเลือกเพื่อรักษาข้อมูลเมตาที่แปลกใหม่เช่น ACLs และฮาร์ดลิงก์


readlink ทำเพียงขั้นตอนเดียวสำหรับการอ่านการเชื่อมโยง ตัวอย่างเช่นในอูบุนตูเรามี / bin / zsh, ซึ่งเชื่อมโยงกับ / etc / Alternatives / zsh, แต่นี่คือ symlink ตัวที่สอง ในที่สุดเราจะไม่ได้รับไฟล์จริงหรือเส้นทางไดเรกทอรี เช่นเดียวกันกับคำสั่ง stat readlink พร้อมตัวเลือก -f เท่านั้นที่สามารถแก้ไขได้ทั้งหมด
Znik

9

ผมใช้คำสั่งls, ,statreadlink

ใช้ไฟล์/etc/localtimeเป็นตัวอย่าง

[flying@lempstacker ~]$ ls /etc/localtime 
/etc/localtime
[flying@lempstacker ~]$ ls -l /etc/localtime
lrwxrwxrwx. 1 root root 35 Aug  2 22:41 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai

การทำงาน

ใช้สถิติ

[flying@lempstacker ~]$ stat /etc/localtime
  File: ‘/etc/localtime’ -> ‘../usr/share/zoneinfo/Asia/Shanghai’
  Size: 35          Blocks: 0          IO Block: 4096   symbolic link
Device: fd01h/64769d    Inode: 272202388   Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-11-23 09:00:59.999887800 +0800
Modify: 2016-08-02 22:41:26.090389904 +0800
Change: 2016-08-02 22:41:26.090389904 +0800
 Birth: -
[flying@lempstacker ~]$ stat -c "%N" /etc/localtime
‘/etc/localtime’ -> ‘../usr/share/zoneinfo/Asia/Shanghai’

ใช้readlink

[flying@lempstacker ~]$ readlink /etc/localtime
../usr/share/zoneinfo/Asia/Shanghai
[flying@lempstacker ~]$ readlink -f /etc/localtime
/usr/share/zoneinfo/Asia/Shanghai

ดูเหมือนว่าคำสั่งreadlink -fนั้นจะดีกว่า

คำอธิบาย

-f, --canonicalize: canonicalize โดยทำตามทุก symlink ในทุกองค์ประกอบของชื่อที่กำหนดซ้ำ; ทั้งหมดยกเว้นองค์ประกอบสุดท้ายจะต้องมีอยู่ —— จากman readlink


6

สถิติจะให้ข้อมูลนี้แก่คุณ:

$ stat current
  File: `current' -> `/home/user/releases/build/'
  ...

readlink ทำเพียงขั้นตอนเดียวสำหรับการอ่านการเชื่อมโยง ตัวอย่างเช่นในอูบุนตูเรามี / bin / zsh, ซึ่งเชื่อมโยงกับ / etc / Alternatives / zsh, แต่นี่คือ symlink ตัวที่สอง ในที่สุดเราจะไม่ได้รับไฟล์จริงหรือเส้นทางไดเรกทอรี เช่นเดียวกันกับคำสั่ง stat readlink พร้อมตัวเลือก -f เท่านั้นที่สามารถแก้ไขได้ทั้งหมด
Znik

5

คุณสามารถทำได้

readlink -f `which command`

หรือคุณจะได้อะไรทำนองนี้ใน Linux ด้วย

stat `which command` | grep File

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

readlink -f "`which command`" 

สถิติและ realink ที่ไม่มี -f ทำเพียงขั้นตอนเดียว แล้วโทรหา readlink -f ดีกว่า
Znik

3

realpath <symlink>ผมจะใช้

อาจเป็นสิ่งที่คุณเรียกว่า 'แหล่งที่มา' เป็นไฟล์ 'เป้าหมาย' ตามการใช้งานของln:Usage: ln [OPTION]... [-T] TARGET LINK_NAME


ขอบคุณมันใช้งานได้เหมือนมีเสน่ห์! ด้วย Mac OSX! ที่readlinkไม่ตัดมัน ... แม็คโง่ lol
JayRizzo

0

readlink -f 'which java' ไม่ได้ผลสำหรับฉัน

แต่สิ่งนี้ทำ:

readlink -f $(which java)

3
ไม่ได้ผลเพราะมัน`ไม่ใช่'.. แต่$()เป็นการฝึกฝนที่ดีกว่า
Stephen Rauch

ทำไมต้องลงคะแนน คำตอบของฉันคือทางเลือกที่ยอมรับได้และเป็นความคิดเห็นที่บอกว่าเป็นการปฏิบัติที่ดีกว่า
NonCreature0714

1
คนส่วนใหญ่ที่ลงคะแนนเสียงไม่ได้แสดงความคิดเห็นด้วยดังนั้นการขอคำอธิบายเกี่ยวกับการลงคะแนนเสียงจะไม่ค่อยให้คำอธิบายแก่คุณเพราะผู้ลงคะแนนเสียงได้ออกไปแล้วและไม่น่าจะกลับมาอีก ฉันขอแนะนำให้คุณลบรหัสที่พิมพ์ผิดที่ไม่ได้ผลจากคำตอบของคุณ ฉันยินดีที่จะลงคะแนนเสียงหากคุณสละเวลาในการทำความสะอาดและอธิบายว่าเพราะเหตุใดจึง$()มีวิธีปฏิบัติที่ดีกว่า
สตีเฟ่น Rauch

ดังที่สตีเฟนอธิบายให้คุณฟัง 'ไม่ใช่' คุณควรแค็ปซูลโดยcommandแต่สิ่งนี้เลิกใช้แล้ว การใช้ $ () ดีกว่าเนื่องจากการห่อหุ้ม $ ($ (คำสั่ง)) นั้นง่ายกว่ามากและไม่ต้องการการหลบหลีกพิเศษ จากนั้นเป็นที่ต้องการ ในตัวอย่างแรกของคุณคุณใช้เครื่องหมายอะโพสโทรฟีปกติแล้ว readlink พยายามค้นหาไฟล์ชื่อ 'java ใด' ที่มีช่องว่างในชื่อ แต่คุณตั้งใจที่จะเรียกคำสั่งที่มีอาร์กิวเมนต์ java สำหรับการหาเส้นทางปฏิบัติการไบนารีจาวา
Znik

0

ใน MAC OX พารามิเตอร์ "-f" ไม่ทำงานการ 'readlink' จะทำงานโดยไม่มีพารามิเตอร์ใด ๆ

KZs-MacBook-Pro:bin kz$ readlink -f pip3
readlink: illegal option -- f
usage: readlink [-n] [file ...]

KZs-MacBook-Pro:bin kz$ readlink pip3
../../../Library/Frameworks/Python.framework/Versions/3.7/bin/pip3
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.