วิธีคัดลอกลิงก์สัญลักษณ์?


180

ฉันมีไดเรกทอรีที่มีลิงก์สัญลักษณ์:

user@host:include$ find .. -type l -ls
4737414    0 lrwxrwxrwx   1 user group       13 Dec  9 13:47 ../k0607-lsi6/camac -> ../../include
4737415    0 lrwxrwxrwx   1 user group       14 Dec  9 13:49 ../k0607-lsi6/linux -> ../../../linux
4737417    0 lrwxrwxrwx   1 user group       12 Dec  9 13:57 ../k0607-lsi6/dfc -> ../../../dfc
4737419    0 lrwxrwxrwx   1 user group       17 Dec  9 13:57 ../k0607-lsi6/dfcommon -> ../../../dfcommon
4737420    0 lrwxrwxrwx   1 user group       19 Dec  9 13:57 ../k0607-lsi6/dfcommonxx -> ../../../dfcommonxx
4737421    0 lrwxrwxrwx   1 user group       17 Dec  9 13:57 ../k0607-lsi6/dfcompat -> ../../../dfcompat

ฉันต้องการคัดลอกไปยังไดเรกทอรีปัจจุบัน ลิงก์ที่เป็นผลลัพธ์ควรเป็นอิสระจากต้นแบบและนำไปสู่วัตถุเป้าหมายโดยตรง

  • cp -s สร้างลิงค์ไปยังลิงค์ที่ไม่เหมาะสม
  • cp -s -L ปฏิเสธที่จะคัดลอกลิงก์ไปยังไดเรกทอรี
  • cp -s -L -r ปฏิเสธที่จะคัดลอกลิงก์ที่เกี่ยวข้องไปยังไดเรกทอรีที่ไม่ทำงาน

ฉันควรทำอย่างไร?


10
cp -dทำให้งานอยู่ข้างฉัน
m-ric

2
cp -Rใน mac
Mirko

คำตอบ:


201
cp --preserve=links

จากหน้าคน:

   --preserve[=ATTR_LIST]
          preserve  the   specified   attributes   (default:   mode,owner-
          ship,timestamps),  if  possible  additional attributes: context,
          links, xattr, all

ส่วนตัวผมใช้cp -av สำหรับการทำสำเนาหนักส่วนใหญ่ ด้วยวิธีนี้ฉันสามารถรักษาทุกอย่าง - แม้ซ้ำ - และดูผลลัพธ์ แน่นอนว่าเป็นเพียงการตั้งค่าส่วนตัว

สำหรับสาเหตุที่ตัวเลือกอื่น ๆ ของคุณไม่ได้ทำตามที่คุณคาดไว้ให้-sสร้างลิงก์แทนการคัดลอกและ-Lติดตามลิงก์ในแหล่งที่มาเพื่อค้นหาไฟล์ที่จะคัดลอกแทนที่จะคัดลอกลิงก์เอง


3
คุณอาจต้องเพิ่ม-Rเพราะมิฉะนั้น cp จะข้ามไดเรกทอรีและ symlink ไปยังไดเรกทอรี
Olivier 'Ölbaum' Scherler

8
ฉันลองทำสิ่งนี้ด้วยสีแดงและมันใช้งานไม่ได้
Mansuro

41
บน Mac หรือ ใช้cp -a
Steve Tauber

11
+1 สำหรับ-aตัวเลือก เฮ้ฉันได้ค้นหาตัวเลือกในcpmanpage ของนับครั้งไม่ถ้วน แต่ฉันจะต้องอ่านอย่างนี้เสมอ ฉันมีจนถึงตอนนี้ใช้-dprแต่-aครอบคลุมทั้งหมดเหล่านั้นรวมถึงการเก็บรักษาคุณสมบัติอื่น ๆ สองสาม หากฉันต้องการคุณสมบัติอื่น ๆ เหล่านี้ฉันอาจจะต้องค้นหา--preserveตัวเลือกอีกครั้งและใช้-dr --preserve=allซึ่งก็คือสิ่งที่-aเป็น! อย่างน้อยฉันก็รู้ตอนนี้ - -aสมบูรณ์แบบและนี่คือสิ่งที่ฉันจะใช้นับจากนี้เป็นต้นไป
James Haigh

3
สิ่งนี้ใช้ไม่ได้กับ Cygwin --preserve=linksไม่เพียงพอ cp: omitting directoryมันก็ยังคงกล่าวว่า แต่-avได้ผล
Chloe

44

-Pเช่นเดียวกับหน้าคนกล่าวว่าการใช้งาน


8
บน Mac -Pไม่สามารถใช้งานไดเรคทอรีได้ดังนั้นฉันจึงใช้งานcp -a
Steve Tauber

4
ขอบคุณฉันเห็นและได้รับประโยชน์จากคำตอบของคุณ 3 ครั้งในขณะนี้แตกต่างกันไปในแต่ละปี ดูเหมือนจะจำไม่ได้!
Siddhartha

ใช้งานได้ แต่หน้าคนของฉันบอกว่า "-P ไม่เคยติดตามลิงก์สัญลักษณ์ใน SOURCE" ซึ่งไม่เหมือนกันโดยสังเขปเช่น "คัดลอก symlinks เป็น symlinks ไปยังปลายทาง" ("ไม่ติดตาม" ทำให้ฟังดูเหมือนทำงานร่วมกับ -R)
RM

สิ่งนี้cp -Pต่างจากคำตอบที่ได้รับการโหวตสูงสุดจาก @kainosnous สำหรับฉัน ขอบคุณ!
tommy.carstensen

ทำงานบน Redhat การตอบรับที่ยอมรับไม่ทำงาน!
Phiber

29

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

ln -s $(readlink -f old/dir/oldlink) new/dir/newlink

หากการรักษาเส้นทางญาติเป็นสิ่งที่คุณต้องการกว่าตัวเลือก-Pของcpดังที่กล่าวโดย Ignacio Vazquez-Abrams เป็นสิ่งที่คุณต้องการ


1
มันอาจเป็นความคิดที่ดีที่จะอ้างถึงซ้ำถ้าสิ่งที่คุณพยายามทำคือการเปลี่ยน symlink จากการสัมพันธ์กับสัมบูรณ์ การเรียกซ้ำไม่จำเป็นต้องใช้ที่นี่และบางครั้งการเชื่อมโยงที่ถูกล่ามโซ่ก็มีเหตุผล Symlinks มักใช้เพื่อระบุตัวเลือกหรือตัวเลือกการกำหนดค่า ตัวอย่างเช่นในระบบของฉันมีการเชื่อมโยง symlink /usr/share/dict/words -> /etc/dictionaries-common/words -> /usr/share/dict/british-englishซึ่งระบุพจนานุกรมที่ต้องการ หากคุณต้องตรวจสอบซ้ำโซ่นี้ symlink ที่เป็นผลลัพธ์จะไม่สนใจการเปลี่ยนแปลงใด ๆ ในการตั้งค่านี้ในอนาคต
James Haigh

24

ตามที่มีบางคนแสดงความคิดเห็น:

cp -a 

ทำได้ดี.

จากคน:

-a    same as -dR --preserve=all

-R    copy directories recursively
-d    same as --no-dereference --preserve=links
--no-dereference   never follow symbolic links in SOURCE

3
... แต่เฉพาะในกรณีที่ไม่มีการเชื่อมโยงไปยังเส้นทางญาติ
Michael Scheper

11

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

cp -Prv /sourcer_dir/* /target_dir

10

ส่วนใหญ่เวลาที่ฉันต้องการคัดลอกลิงก์สัญลักษณ์หลายอันฉันจริง ๆ แล้วพยายามจำลองแผนผังไดเรกทอรี ดังนั้นฉันต้องการ symlink และทุกอย่างอื่น

นี่คือ overkill สำหรับการคัดลอกเพียงไม่กี่ symlink แต่ถ้าคุณกำลังพยายามที่จะคัดลอกแผนภูมิทั้งหมดจริง ๆ นี้มีประโยชน์มาก:

ใช้tar

user@host:/cwd$ ( cd /path/to/src ; tar cf - . ) | ( cd /path/to/dest ; tar xf - )

tarไม่ได้แก้ไข symlink ตามค่าเริ่มต้นดังนั้น symlink ในสำเนาของมิเรอร์จะชี้ไปที่ตำแหน่งเดียวกับที่อยู่ในแผนผังต้นกำเนิด

เคล็ดลับนี้ใช้ประโยชน์จาก subshells เพื่อให้คำสั่งtarอยู่ในตำแหน่งที่รูทของไดเรกทอรีที่จะทำมิรเรอร์ คุณสามารถออกจากหนึ่งในนั้น (พร้อมกับคำสั่งcd ที่เกี่ยวข้อง) หากคุณอยู่ในไดเรกทอรีsrcหรือdest :

# already in src?
user@host:/src$ tar cf - . | ( cd /path/to/dest ; tar xf - )

# already in dest?
user@host:/dest$ ( cd /path/to/src ; tar cf - . ) | tar xf - 

# just need src/foo?
# this result will be a mirror copy at dest/foo 
user@host:/src$ tar cf - foo | ( cd /path/to/dest ; tar xf - )

# mirror to another system?
user@host:/src$ tar cf - . | ssh user@example.com '( cd /path/to/dest ; tar xf - )'

อีกครั้งสิ่งนี้ไม่เหมาะสำหรับทุกครั้งที่คุณต้องการคัดลอกลิงก์สัญลักษณ์ แต่เป็นข้อมูลที่มีประโยชน์มากที่ควรทราบ


1
tar เป็นแบบพกพามากกว่า cp แน่นอน
don bright

4

ลอง: cp -pr symlink ปลายทาง

[root@station1 temp]# ls -l
total 8
-rw-r--r-- 1 root root  0 Jul 27 18:40 abc
lrwxrwxrwx 1 root root 13 Jul 27 18:41 abc.link1 -> /tmp/temp/abc
[root@station1 temp]# cp -rp /tmp/temp/abc.link1 /tmp/temp/abc.link2
[root@station1 temp]# ls -l
total 12
-rw-r--r-- 1 root root  0 Jul 27 18:40 abc
lrwxrwxrwx 1 root root 13 Jul 27 18:41 abc.link1 -> /tmp/temp/abc
lrwxrwxrwx 1 root root 13 Jul 27 18:42 abc.link2 -> /tmp/temp/abc
[root@station1 temp]# 

ระบบปฏิบัติการ - Centos 5 (Linux)


3

บน Ubuntu เมื่อคัดลอกลิงก์และไฟล์ในไดเรกทอรี:

cp --no-dereference --preserve=links

5
cp -dคือชวเลขในการนี้
hunse

1
ฉันคิดว่าทั้งคู่cp -aและcp --preserve=linksทำมากกว่าคำถามที่ถาม ตามที่ฉันเข้าใจแล้วนี่เป็นคำตอบที่ถูกต้องสำหรับทุกคนที่ใช้cpแม้ว่าไฟล์เท่านั้น (ไม่มีไดเรกทอรี) เหมือนในคำถาม--no-dereferenceจะไม่มีผลใด ๆ
palswim

2

ใช้-Pตัวเลือกขณะที่อิกนาซิโอ Vazquez อับราฮัมเขียนข้างต้น สิ่งที่เขาไม่ได้พูดถึงคือไม่มีผลโดยไม่ต้อง-P ดังนั้นคุณต้องไม่น้อยกว่า-Rcp -RP

(เว็บไซต์ยังไม่ให้ความเห็นฉันเลยโพสต์คำตอบแยกต่างหาก)


ในกล่อง Solaris เก่า cp ของฉันไม่รองรับ -d cp -rP ทำงานให้ฉัน; (idk ความแตกต่างระหว่าง -R และ -r, -r ใช้ได้สำหรับฉัน)
นักเลง

1

cp -s และ cp -L เป็นคำสั่งพิเศษ สำหรับความต้องการของคุณใช้ไม่มี

เช่นการคัดลอกไดเรกทอรี DIR ที่มีและลิงค์สัญลักษณ์ b ชี้ไปที่

  • cp -s DIR / * N / สร้างลิงค์สัญลักษณ์แทนการคัดลอก, N / a -> ../ DIR / a (ลิงค์) และ N / b -> (../ DIR / b) ซึ่งลิงค์ไปยังลิงค์
  • cp -L DIR / * N / คัดลอกพร้อมการยกเลิกการเชื่อมโยงลิงก์, N / a, N / b (เหมือนกับ DIR / a)

สิ่งที่คุณต้องการคือ N / a (= DIR / a) และ N / b -> ../ N / a; ดังนั้นเพียงแค่คัดลอกโดยไม่ต้องทำการอ้างอิงโดยใช้ตัวเลือก cp -P ฉันเชื่อว่านี่เป็นค่าเริ่มต้นสำหรับ cp ด้วย

  • -P ไม่มีการอ้างอิงรักษาลิงค์
  • -d รวมตัวเลือก -P กับ -p เพื่อรักษาโหมด =, ความเป็นเจ้าของ, การประทับเวลา
  • - รวมตัวเลือก -d กับ -R เพื่อคัดลอกไดเรกทอรีซ้ำ

อ้างถึงman cpหรือcp --helpสำหรับตัวเลือกเพิ่มเติม

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