การทำสมนามไฟล์ Symlink ในไดเรกทอรีย่อยโดยไม่เปลี่ยนไดเรกทอรีปัจจุบัน


11

ดูเหมือนว่าควรเชื่อมโยงไฟล์หนึ่งไฟล์กับไฟล์ใหม่ในไดเรกทอรีย่อย .... โดยไม่ต้องย้ายไดเรกทอรีย่อย แต่สิ่งที่เกี่ยวกับไวยากรณ์นั้นน่างงงวยและตอบโต้กับสิ่งที่ฉันคาดหวัง นี่คือกรณีทดสอบ:

mkdir temp
cd temp
mkdir deploy
echo "Contents of the build file!" > deploy/resources.build.php
ln -s deploy/resources.build.php deploy/resources.php
cat deploy/resources.php #bad symlink

นี่เป็นเพียงการสร้าง symlink ที่ใช้งานไม่ได้! ฉันกำลังเรียกใช้สิ่งนี้ในสคริปต์การตั้งค่าสภาพแวดล้อมการสร้างดังนั้นฉันต้องการหลีกเลี่ยงการเปลี่ยนไดเรกทอรีการทำงานปัจจุบันหากเป็นไปได้

ln -s deploy/resources.build.php resources.php
cat deploy/resources.php

ยังใช้งานไม่ได้เพราะมันสร้าง symlink ในไดเรกทอรีชั่วคราวแทนไดเรกทอรีย่อยปรับใช้

cd deploy
ln -s resources.build.php resources.php
cd ..

ใช้งานได้ แต่ฉันต้องการทราบวิธีการทำโดยไม่ต้องเปลี่ยนไดเรกทอรี

ใช้เส้นทางแบบเต็มเช่น:

/home/whatever/src/project/temp/stuff/temp/deploy/resources.build.php

ใช้งานได้ แต่ไม่แปลกและค่อนข้างทำไม่ได้โดยเฉพาะอย่างยิ่งในสภาพแวดล้อมการสร้างที่ทุกสิ่งในโครงการอาจแตกต่างกันระหว่างการสร้างและสิ่งที่คล้ายกัน

ฉันจะสร้าง symlink ระหว่างสองไฟล์ในไดเรกทอรีย่อยโดยไม่ย้ายไปยังไดเรกทอรีย่อยนั้นหรือไม่และในขณะที่ให้ชื่อใหม่เป็น "นามแฝง" ไฟล์ใหม่

คำตอบ:


10

แต่สิ่งที่เกี่ยวกับไวยากรณ์นั้นน่างงงวยและตอบโต้กับสิ่งที่ฉันคาดหวัง

ข้อโต้แย้งสำหรับlnในรูปแบบที่คุณใช้คือ:

ln [OPTION] ... [-T] เป้าหมาย LINK_NAME (แบบฟอร์มที่ 1)

สิ่งที่น่างงและไม่ได้ใช้งานง่ายคือเมื่อคุณสร้าง symlink อาร์กิวเมนต์เป้าหมายสำหรับlnไม่คาดว่าจะเป็นพา ธ ไปยังไฟล์ แต่จะสร้างเนื้อหาของ symlink หากคุณคิดเกี่ยวกับมันสักครู่มันชัดเจนว่ามันจะต้องเป็นอย่างนั้น พิจารณา:

$ echo foo >foo
$ ln -s foo bar1
$ ln -s $PWD/foo bar2
$ cat bar1
foo
$ cat bar2
foo
$ ls -l bar1 bar2
lrwxrwxrwx 1 matt matt  3 Dec 29 16:29 bar1 -> foo
lrwxrwxrwx 1 matt matt 29 Dec 29 16:29 bar2 -> /home/matt/testdir/foo

ในตัวอย่างนั้นฉันสร้าง 2 symlinks ชื่อ "bar1" และ "bar2" ชี้ไปที่ไฟล์เดียวกัน lsแสดงให้เห็นว่า symlink ตัวเองมีเนื้อหาที่แตกต่างแม้ว่า - หนึ่งมีเส้นทางที่แน่นอนและหนึ่งมีเส้นทางญาติ ด้วยเหตุนี้เราจะทำงานต่อไปแม้ว่ามันจะถูกย้ายไปยังไดเรกทอรีอื่นและสิ่งอื่น ๆ ก็จะไม่:

$ mv bar2 /tmp
$ cat /tmp/bar2
foo
$ mv bar1 /tmp
$ cat /tmp/bar1
cat: /tmp/bar1: No such file or directory

ดังนั้นเมื่อพิจารณาว่าเราจะต้องสามารถสร้างทั้งสัมพัทธ์และ symlink แบบสัมบูรณ์และแม้กระทั่งการสร้าง symlink ที่เสียหายซึ่งจะไม่แตกถ้าไฟล์เป้าหมายถูกสร้างขึ้นในภายหลังอาร์กิวเมนต์เป้าหมายจะต้องตีความเป็นข้อความอิสระแทนที่จะเป็น พา ธ ไปยังไฟล์ที่มีอยู่แล้ว

หากคุณต้องการสร้างไฟล์ชื่อ deploy / resources.php ที่ลิงก์ไปยัง deploy / resources.build.php คุณต้องตัดสินใจว่าคุณต้องการสร้าง symlink แบบสัมบูรณ์ (ซึ่งยืดหยุ่นได้กับ symlink ที่ถูกย้าย แต่จะแตกถ้า เป้าหมายถูกย้าย) หรือ symlink แบบสัมพัทธ์ (ซึ่งจะทำงานต่อไปตราบใดที่ทั้ง symlink และเป้าหมายถูกย้ายเข้าด้วยกันและรักษาเส้นทางสัมพัทธ์เดียวกัน)

ในการสร้าง symlink แบบสัมบูรณ์คุณสามารถทำได้:

$ ln -s $PWD/deploy/resources.build.php deploy/resources.php

ในการสร้างแบบสัมพันธ์คุณต้องหาเส้นทางสัมพัทธ์จากต้นทางไปยังเป้าหมายก่อน ในกรณีนี้เนื่องจากแหล่งที่มาและเป้าหมายอยู่ในไดเรกทอรีเดียวกันซึ่งสัมพันธ์กับอีกไดเรกทอรีหนึ่งคุณสามารถทำได้:

$ ln -s resources.build.php deploy/resources.php

หากพวกเขาไม่ได้อยู่ในไดเรกทอรีเดียวกันคุณจะต้องทำสิ่งที่ต้องการแทน:

$ ln -s ../foo/f bar/b

ในกรณีที่ว่าแม้ว่าfooและbarมีทั้งในไดเรกทอรีปัจจุบันของคุณคุณต้องรวม../เข้าไปในln เป้าหมายเพราะมันอธิบายถึงวิธีการที่จะหาจากไดเรกทอรีที่มีfb

นั่นเป็นคำอธิบายที่ยาวมาก แต่หวังว่ามันจะช่วยให้คุณเข้าใจlnไวยากรณ์ได้ดีขึ้นเล็กน้อย


3

คุณสามารถสร้างลิงค์ใน subshell ได้ดังนี้:

  (cd deploy && ln -s resources.build.php resources.php && cat resources.php)

เมื่อเชลล์ย่อยสิ้นสุดการทำงานคุณจะพบว่าตัวเองยังอยู่ในไดเรกทอรีที่ถูกต้อง

หรือคุณอาจลอง

 ln -s resources.build.php deploy/resources.php

ซึ่งยังใช้งานได้โดยไม่สนใจที่จะรวมไว้ใน CL ความจริงที่ว่าไฟล์ทรัพยากร . build.phpไม่ได้อยู่ในไดเรกทอรีที่คุณกำลังออกคำสั่ง แต่อยู่ในความเป็นจริงภายใน. / Deploy


นี่คือเวทมนตร์สีดำครับ!
Kzqai

1

สิ่งนี้ทำให้ฉันสับสนจนกระทั่งฉันรู้ว่า symlink นั้นเป็นไฟล์กำหนดค่า เช่นฉันจะเขียนข้อมูลเส้นทางนั้นเป็นไฟล์ข้อความธรรมดาได้อย่างไร:

ln -s [target] [link name]

กลายเป็น:

echo [target] > [link name]

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

ln -s /path/doesnt/exist/file.err
ll
file.err -> /path/doesnt/exist/file.err

ดังนั้น:

ln -s deploy/resources.build.php deploy/resources.php

ผลิตไฟล์ simlink ที่เรียกว่าresources.phpใน./deployโฟลเดอร์ที่อ้างอิงไฟล์ในโฟลเดอร์resources.build.php./deploy/deploy/

นั่นไม่น่าเป็นสิ่งที่คุณต้องการและให้ลิงค์ที่ไม่ดี (ขาด) ไม่มีอะไรผิดปกติกับลิงค์ถ้าคุณวางไฟล์นั้นไว้ลิงค์ก็ใช้ได้ อย่างไรก็ตาม (ที่คนอื่นชี้ให้เห็น) สิ่งที่ฉันและ OP ต้องการคือ:

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