Làm thế nào để sao chép các liên kết tượng trưng?


180

Tôi có thư mục chứa một số liên kết tượng trưng:

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

Tôi cần phải sao chép chúng vào thư mục hiện tại. Các liên kết kết quả phải độc lập với các nguyên mẫu của chúng và dẫn trực tiếp đến các đối tượng mục tiêu của chúng.

  • cp -s tạo liên kết đến các liên kết không phù hợp với hành vi.
  • cp -s -L từ chối sao chép liên kết đến thư mục
  • cp -s -L -r từ chối sao chép các liên kết tương đối vào thư mục không hoạt động

Tôi nên làm gì?


10
cp -dlàm công việc về phía tôi
m-ric

2
cp -Rtrên máy mac
Mirko

Câu trả lời:


201
cp --preserve=links

Từ trang người đàn ông:

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

Cá nhân, tôi sử dụng cp -av cho hầu hết các bản sao nặng của tôi. Bằng cách đó, tôi có thể bảo toàn mọi thứ - thậm chí đệ quy - và xem đầu ra. Tất nhiên, đó chỉ là sở thích cá nhân.

Về lý do tại sao các tùy chọn khác của bạn không làm những gì bạn mong đợi, hãy -stạo một liên kết thay vì sao chép và -Ltheo các liên kết trong nguồn để tìm tệp cần sao chép thay vì tự sao chép các liên kết.


3
Bạn có thể cần phải thêm -R, vì nếu không cp sẽ bỏ qua các thư mục và symlink đến thư mục.
Olivier 'Ölbaum' Scherler

8
Tôi đã thử điều này trên redhat và nó không hoạt động
Mansuro

41
trên máy Mac? sử dụngcp -a
Steve Tauber

11
+1 cho -atùy chọn. Heh, tôi đã tìm kiếm các tùy chọn trong cpmanpage vô số lần, nhưng tôi phải luôn lướt qua cái này. Tôi đã sử dụng cho đến bây giờ -dpr, nhưng -abao gồm tất cả những thứ đó, cộng với việc bảo tồn một vài thuộc tính khác. Nếu tôi cần các thuộc tính khác này, có lẽ tôi đã tìm lại --preservetùy chọn và sử dụng -dr --preserve=all, đó chính xác -alà cái gì ! Ít nhất tôi biết bây giờ - -alà hoàn hảo và đây là những gì tôi sẽ sử dụng từ bây giờ.
James Haigh

3
Điều này đã không làm việc trên Cygwin. --preserve=linkskhông đủ Nó vẫn nói cp: omitting directory. Nhưng -avđã làm việc.
Chloe

44

Giống như trang người đàn ông nói, sử dụng -P.


8
trên Mac -Pkhông hoạt động trên các thư mục nên tôi đã sử dụngcp -a
Steve Tauber

4
Cảm ơn, tôi đã thấy và hưởng lợi từ câu trả lời của bạn 3 lần bây giờ khác nhau trong một năm. Dường như không thể nhớ nó!
Siddhartha

Điều này hoạt động, nhưng trang người đàn ông của tôi nói "-P không bao giờ theo các liên kết tượng trưng trong SOURCE", không trực quan giống như "sao chép liên kết tượng trưng như liên kết đến đích". ("không bao giờ theo dõi" làm cho nó có vẻ như nó hoạt động kết hợp với -R)
RM

Điều này cp -Pkhông giống như câu trả lời được bình chọn hàng đầu bởi @kainosnous làm việc cho tôi. Cảm ơn!
tommy.carstensen

Hoạt động trên Redhat. Các phản ứng được chấp nhận không hoạt động!
Phiber

29

Nếu các liên kết chứa các đường dẫn tương đối, thì, sao chép liên kết sẽ không điều chỉnh đường dẫn tương đối. Sử dụng readlink, với công tắc -fđể theo dõi đệ quy, để có được đường dẫn tuyệt đối của liên kết. Ví dụ:

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

Nếu duy trì các đường dẫn tương đối là những gì bạn muốn, so với các tùy chọn -Pcủa cp, như đã nói bởi Ignacio Vazquez-Abrams, là những gì bạn cần.


1
Có thể là một ý tưởng tồi đối với việc quy định đệ quy nếu tất cả những gì bạn đang cố gắng làm là chuyển đổi các liên kết tượng trưng từ tương đối thành tuyệt đối. Sự đệ quy là không cần thiết ở đây, và đôi khi các chuỗi liên kết chuỗi có ở đó vì một lý do. Symlinks thường được sử dụng để xác định các lựa chọn hoặc tùy chọn cấu hình. Ví dụ, trên hệ thống của tôi có một chuỗi liên kết tượng trưng /usr/share/dict/words -> /etc/dictionaries-common/words -> /usr/share/dict/british-englishchỉ định từ điển ưa thích. Nếu bạn định đệ quy chuỗi này, symlink kết quả sẽ bỏ qua mọi thay đổi trong tương lai đối với tùy chọn này.
James Haigh

24

Như một số ít đã bình luận:

cp -a 

hoạt động tốt

Từ người đàn ông:

-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
... nhưng chỉ khi không có liên kết tượng trưng nào đến đường dẫn tương đối.
Michael Scheper

11

Tôi đã sử dụng sau đây để sao chép một thư mục thực sự lớn. Tất cả các liên kết tượng trưng được bảo tồn, bản sao được thực hiện đệ quy và tôi có thể có một số phản hồi trực quan của quá trình:

cp -Prv /sourcer_dir/* /target_dir

10

Hầu hết thời gian, khi tôi cần sao chép nhiều liên kết tượng trưng, ​​tôi thực sự đang cố gắng phản chiếu một cây thư mục. Vì vậy, tôi muốn các liên kết tượng trưng và mọi thứ khác.

Điều này là quá mức cần thiết để sao chép chỉ một vài liên kết tượng trưng, ​​nhưng nếu bạn thực sự cố gắng sao chép toàn bộ một cây, điều này có thể rất hữu ích:

Sử dụng nhựa đường .

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

tar không giải quyết liên kết tượng trưng theo mặc định, vì vậy các liên kết tượng trưng trong bản sao nhân bản sẽ trỏ đến cùng vị trí với các vị trí trong cây gốc.

Thủ thuật này sử dụng các subshells để đưa lệnh tar vào vị trí ở thư mục gốc của thư mục được nhân đôi; bạn có thể loại bỏ một trong số chúng (cùng với lệnh cd được liên kết ) nếu bạn đã có trong thư mục src hoặc 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 - )'

Một lần nữa, điều này không phù hợp cho mỗi lần bạn muốn sao chép các liên kết tượng trưng, ​​nhưng nó là một đoạn rất hữu ích để biết.


1
tar chắc chắn là dễ mang theo hơn cp theo kinh nghiệm của tôi
đừng sáng

4

Hãy thử: cp -pr symlink đích

[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]# 

HĐH - Centos 5 (Linux)


3

Trên Ubuntu khi sao chép liên kết và tệp trong một thư mục:

cp --no-dereference --preserve=links

5
cp -dlà cách viết tắt cho điều này
hunse

1
Tôi nghĩ cả hai cp -acp --preserve=linkslàm nhiều hơn câu hỏi đang hỏi. Theo tôi hiểu, đây là câu trả lời chính xác cho bất kỳ ai sử dụng cp, mặc dù chỉ với các tệp (không có thư mục) như trong câu hỏi, --no-dereferencesẽ không có hiệu lực.
palswim

2

Sử dụng -Ptùy chọn, khi Ignacio Vazquez-Abrams đã viết ở trên . Những gì anh không đề cập là -Pkhông có hiệu lực mà không có -R. Vì vậy, bạn cần ít nhất cp -RP.

(Trang web không cho phép tôi nhận xét nên tôi đã đăng câu trả lời riêng.)


Trên hộp solaris cũ, cp của tôi không hỗ trợ -d. cp -rP làm việc cho tôi; (idk sự khác biệt giữa -R và -r, -r hoạt động với tôi).
kẻ gây rối

1

cp -s và cp -L là các lệnh đặc biệt. Đối với yêu cầu của bạn, không sử dụng.

ví dụ: Sao chép thư mục TRỰC TIẾP chứa a và liên kết tượng trưng b trỏ đến a.

  • cp -s DIR / * N / tạo một liên kết tượng trưng thay vì sao chép, N / a -> ../ DIR / a (liên kết) và N / b -> (../ DIR / b) là liên kết đến một liên kết
  • cp -L TRỰC TIẾP / * N / bản sao với hội nghị liên kết, N / a, N / b (giống như DIR / a)

Những gì bạn cần là N / a (= DIR / a) và N / b -> ../ N / a; vì vậy chỉ cần sao chép mà không cần hội nghị, sử dụng tùy chọn cp -P. Tôi tin rằng đây cũng là mặc định cho cp.

  • -P không có trách nhiệm, giữ liên kết
  • -d kết hợp tùy chọn -P với -p để giữ = chế độ, quyền sở hữu, dấu thời gian
  • -a kết hợp tùy chọn -d với -R để sao chép thư mục

tham khảo man cphoặc cp --helpđể có thêm lựa chọn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.