ln -s พร้อมกับพา ธ ที่สัมพันธ์กับ pwd


26

ฉันพยายามสร้างลิงก์สัญลักษณ์มากมาย แต่ฉันไม่สามารถเข้าใจได้ว่าทำไมสิ่งนี้ถึงใช้งานได้

ln -s /Users/niels/something/foo ~/bin/foo_link

ในขณะนี้

cd /Users/niels/something
ln -s foo ~/bin/foo_link

ไม่ใช่.

ฉันเชื่อว่ามีบางอย่างเกี่ยวข้องกับการfoo_linkเชื่อมโยงไปยัง foo /Users/niels/binแทน/Users/niels/something

ดังนั้นคำถามคือฉันจะสร้างลิงก์สัญลักษณ์ที่ชี้ไปยังเส้นทางที่แน่นอนได้โดยไม่ต้องพิมพ์ได้อย่างไร

สำหรับการอ้างอิงฉันใช้ Mac OS X 10.9 และ Zsh

คำตอบ:


33

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

ln -s "$(pwd)/foo" ~/bin/foo_link

target(ตอนแรก) อาร์กิวเมนต์สำหรับln -sคำสั่งทำงานเทียบกับสถานที่การเชื่อมโยงสัญลักษณ์ไม่ใช่ไดเรกทอรีปัจจุบันของคุณ ช่วยให้ทราบว่าโดยพื้นฐานแล้ว symlink ที่สร้างขึ้น (อาร์กิวเมนต์ที่สอง) จะเก็บข้อความที่คุณให้ไว้สำหรับอาร์กิวเมนต์แรก

ดังนั้นหากคุณทำสิ่งต่อไปนี้:

cd some_directory
ln -s foo foo_link

จากนั้นย้ายลิงก์ไปรอบ ๆ

mv foo_link ../some_other_directory
ls -l ../some_other_directory

คุณจะเห็นว่าfoo_link พยายามที่จะชี้ไปfooยังไดเรกทอรีที่มันอาศัยอยู่นอกจากนี้ยังทำงานร่วมกับลิงก์สัญลักษณ์ที่ชี้ไปยังเส้นทางสัมพัทธ์ หากคุณทำสิ่งต่อไปนี้:

ln -s ../foo yet_another_link

แล้วย้าย yet_another_link../fooไปยังไดเรกทอรีอื่นและตรวจสอบที่จะชี้ไปที่คุณจะเห็นว่ามันก็ชี้ไปที่ นี่เป็นพฤติกรรมที่ตั้งใจเนื่องจากลิงก์สัญลักษณ์หลายครั้งอาจเป็นส่วนหนึ่งของโครงสร้างไดเรกทอรีที่สามารถอยู่ในเส้นทางสัมบูรณ์ต่างๆ

ในกรณีของคุณเมื่อคุณสร้างลิงค์โดยพิมพ์

ln -s foo ~/bin/foo_link

foo_linkเพียงแค่เก็บลิงค์ไปยังfooสัมพันธ์กับที่ตั้งของมัน การใส่$(pwd)ชื่อของอาร์กิวเมนต์เป้าหมายไว้ด้านหน้าจะเป็นการเพิ่มพา ธ สัมบูรณ์ของไดเร็กทอรีการทำงานปัจจุบันเพื่อให้ลิงก์ถูกสร้างขึ้นด้วยเป้าหมายที่แน่นอน


"... ช่วยจินตนาการว่า symlink ที่สร้างขึ้นนั้นมีเพียงข้อความ .... " นี่ไม่ใช่ความจริงตามตัวอักษรใช่หรือไม่
Wildcard

1
มันคือ. บางทีฉันอาจเปลี่ยนจินตนาการเป็น "รู้" หรือ "เข้าใจ"
Achilleas

บางทีฉันอาจสับสนตัวเองอีกครั้ง ดูเหมือนที่คุณพูดว่า "เป้าหมาย" คุณหมายถึง "แหล่งที่มา" source_file(ตอนแรก) อาร์กิวเมนต์เป็นที่จุดเชื่อมโยงซึ่งเป็นคำต่อคำสิ่งที่คุณใส่ในคำสั่ง target_file(สอง) อาร์กิวเมนต์จะกลายเป็นชื่อของการเชื่อมโยงเว้นแต่สิ่งที่คุณใส่เป็นไดเรกทอรีซึ่งในกรณีนี้ชื่อของการเชื่อมโยงเป็นเช่นเดียวกับ basename ของแต่วางไว้ในไดเรกทอรีsource_file target_file
Charlie Gorichanaz

ที่คุณกำลังขวา̶̶t̶h̶e̶r̶e̶'̶s̶ความผิดพลาดใน̶a̶n̶s̶w̶e̶r̶.̶บ้าวิธีการที่จะไม่อนุญาตได้รับการติด̶s̶o̶o̶n̶e̶r̶.̶̶F̶i̶x̶i̶n̶g̶.̶ไม่มีคำตอบที่ถูกต้อง โดยlnmanpage targetเป็นอาร์กิวเมนต์แรก (ที่ลิงก์ชี้ไปที่ ) ในขณะที่อาร์กิวเมนต์ที่สองนั้นเรียกง่าย ๆ ว่าlink( sourceไม่ได้กล่าวถึง)
Achilleas

3
ใน linux (gnu ln) man page จะเรียกอาร์กิวเมนต์แรกtargetและตัวที่สองlink( man7.org/linux/man-pages/man1/ln.1.html ) แต่ใน BSD (รวมถึง OS X) ตัวแรกจะถูกเรียกsourceและตัวที่สองtarget( freebsd.org/cgi/man.cgi?ln ) ค่อนข้างสับสน
cristoper

5

การใช้ธง-r( --relative) จะทำให้งานนี้:

ln -sr foo ~/bin/foo_link

4
ระวังนั่น-rคือ GNUism เช่นไม่ใช่ POSIX ดังนั้นจะไม่ทำงานในกรณี OP เนื่องจากlnคำสั่งOS X มาตรฐานนั้นใช้ BSD
jlliagre

2

หากต้องการบันทึกการพิมพ์คุณสามารถทำได้

ln -s "$PWD"/foo ~/bin/foo_link

@ เฟรดดี้มันขึ้นอยู่กับเปลือก ในปลาหรือ zsh มันก็โอเค ในบอร์นเหมือนเปลือกหอยรวมทั้งทุบตีและค่าเริ่มต้นของ $ IFS, SPC แน่นอนจะเป็นปัญหา แต่ยัง TAB, NL และตัวอักษร globbing ทั้งหมด (อย่างน้อย*, ?และ[...])
Stéphane Chazelas

@ StéphaneChazelasใช่คุณพูดถูกและมีการติดแท็กคำถามbashดังนั้นจึงเป็นความคิดที่ดีที่จะเสนอราคา ไม่ดีของฉันฉันควรจะเจาะจงมากขึ้น
Freddy

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