วิธีตรวจสอบเป้าหมายของลิงก์สัญลักษณ์ที่มีสัญลักษณ์ไปยังเส้นทางที่ต้องการ


16

ภายในสคริปต์ทุบตีฉันรู้ว่าฉันสามารถตรวจสอบว่าไฟล์เป็นลิงค์สัญลักษณ์ที่มีไวยากรณ์ต่อไปนี้หรือไม่

if [ -L $path ]

ไม่มีใครรู้ว่าฉันจะทดสอบว่าเส้นทางนั้นเชื่อมโยงกับเส้นทางเฉพาะหรือไม่ เช่นผมต้องการที่จะตรวจสอบว่าเป้าหมายของการเป็น$path/some/where



2
คุณหมายถึงการเชื่อมโยงไปโดยเส้นทางโดยเฉพาะ? คุณไม่สามารถทำreadlinkบนเส้นทางที่รู้จักและเปรียบเทียบกับเส้นทางที่คุณกำลังทดสอบหรือไม่?
Bratchley

@Bratchley ใช่นั่นคือสิ่งที่ฉันหมายถึง .. ขอบคุณสำหรับคำตอบ
BillMan

2
ฉันขอแนะนำให้คุณใส่ตัวแปรของเชลล์ในเครื่องหมายคำพูด (เช่นif [ -L "$path" ]) เว้นแต่คุณจะมีเหตุผลที่ดีที่จะไม่ทำและคุณแน่ใจว่าคุณรู้ว่าคุณกำลังทำอะไรอยู่
G-Man กล่าวว่า 'Reinstate Monica'

@ G-Man ขอบคุณสำหรับข้อเสนอแนะที่ยอดเยี่ยม .. ไม่รู้ตัวฉันรู้ว่าจะทำเช่นนั้น แต่ลืมมันในทางปฏิบัติ .. การเสริมกำลังช่วย
BillMan

คำตอบ:


22

หากคุณต้องการตรวจสอบว่า$pathเป็นลิงค์สัญลักษณ์ที่เป็นเป้าหมาย/some/whereหรือไม่คุณสามารถใช้readlinkยูทิลิตีนี้ได้ มันไม่ได้เป็น POSIX แต่มีอยู่ในหลายระบบ (GNU / Linux, BusyBox, * BSD, …)

if [ "$(readlink -- "$path")" = /some/where ]; then 

โปรดทราบว่านี่เป็นการเปรียบเทียบข้อความที่แน่นอน หากเป้าหมายของลิงก์คือ/some//whereหรือถ้าเป็นwhereและค่าของ$pathคือ/some/linkข้อความจะไม่ตรงกัน

readlinkรองรับตัวเลือกหลายเวอร์ชัน-fซึ่งกำหนดเส้นทางให้เป็นมาตรฐานด้วยการขยายลิงก์สัญลักษณ์ทั้งหมด

เชลล์จำนวนมากรวมถึง dash, ksh, bash และ zsh สนับสนุน-efโอเปอเรเตอร์ในtestบิลด์อินเพื่อทดสอบว่าไฟล์สองไฟล์เหมือนกันหรือไม่ (ฮาร์ดลิงก์ไปยังไฟล์เดียวกันหลังจากลิงก์สัญลักษณ์) คุณสมบัตินี้ได้รับการสนับสนุนอย่างกว้างขวาง แต่ไม่ใช่ POSIX

if [ "$path" -ef "/some/where" ]; then 

ตัวอย่างแรกไม่ทำงานเมื่อลิงก์ชี้ไปที่เส้นทางสัมพัทธ์ ...
inemanja

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

0

ในการหลีกเลี่ยงปัญหาเกี่ยวกับเส้นทางสัมพัทธ์และเส้นทางสัมบูรณ์และ "/" ที่ท้ายเส้นทางหรือลิงค์:

if [ "$(realpath $(readlink -- "$path"))" = $(realpath /some/where) ]; then
    echo "Is"
else 
    echo "Is not"
fi

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