Bagaimana cara menyalin tautan simbolis?


180

Saya memiliki direktori yang berisi beberapa tautan simbolis:

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

Saya perlu menyalinnya ke direktori saat ini. Tautan yang dihasilkan harus independen dari prototipe mereka dan mengarah langsung ke objek target mereka.

  • cp -s membuat tautan ke tautan yang bukan perilaku yang pantas.
  • cp -s -L menolak untuk menyalin tautan ke direktori
  • cp -s -L -r menolak untuk menyalin tautan relatif ke direktori yang tidak berfungsi

Apa yang harus saya lakukan?


10
cp -dmembuat pekerjaan di sisiku.
m-ric

2
cp -Rpada mac
Mirko

Jawaban:


201
cp --preserve=links

Dari halaman manual:

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

Secara pribadi, saya menggunakan cp -av sebagian besar salinan berat saya. Dengan begitu, saya bisa menjaga semuanya - bahkan secara rekursif - dan melihat hasilnya. Tentu saja, itu hanya preferensi pribadi.

Mengapa opsi Anda yang lain tidak melakukan apa yang Anda harapkan, -sjadikan tautan alih - alih menyalin dan -Likuti tautan di sumber untuk menemukan file yang akan disalin daripada menyalin tautan itu sendiri.


3
Anda mungkin perlu menambahkan -R, karena jika tidak cp akan melewatkan direktori dan symlink ke direktori.
Olivier 'Ölbaum' Scherler

8
Saya mencoba ini pada redhat dan tidak berhasil
Mansuro

41
di Mac? gunakancp -a
Steve Tauber

11
+1 untuk -aopsi. Heh, aku sudah sering mencari opsi di cphalaman manual, namun aku pasti selalu membaca skim yang satu ini. Saya sampai sekarang telah menggunakan -dpr, tetapi -amencakup semua itu, ditambah pelestarian beberapa atribut lainnya. Jika saya membutuhkan atribut-atribut lain ini, saya mungkin akan mencari --preserveopsi itu lagi dan menggunakan -dr --preserve=all, itulah tepatnya -a! Setidaknya saya tahu sekarang - -asempurna dan inilah yang akan saya gunakan mulai sekarang.
James Haigh

3
Ini tidak berhasil pada Cygwin. --preserve=linksitu tidak cukup. Masih dikatakan cp: omitting directory. Tapi -avberhasil.
Chloe

44

Seperti yang dikatakan halaman manual, gunakan -P.


8
pada Mac -Ptidak bekerja pada direktori jadi saya menggunakancp -a
Steve Tauber

4
Terima kasih, saya telah melihat dan mendapat manfaat dari jawaban Anda 3 kali sekarang berbeda kali dalam setahun. Sepertinya tidak bisa mengingatnya!
Siddhartha

Ini berfungsi, tetapi halaman manual saya mengatakan "-P tidak pernah mengikuti tautan simbolis di SOURCE", yang secara intuisi tidak sama dengan "salin symlink sebagai symlink ke tujuan". ("tidak pernah mengikuti" membuatnya terdengar seperti bekerja dalam kombinasi dengan -R)
RM

Ini cp -Ptidak seperti jawaban terpilih teratas oleh @ainosnous bekerja untuk saya. Terima kasih!
tommy.carstensen

Bekerja pada Redhat. Respons yang diterima tidak berfungsi!
Phiber

29

Jika tautan berisi jalur relatif, maka, menyalin tautan tidak akan menyesuaikan jalur relatif. Gunakan readlink, dengan saklar -funtuk mengikuti secara rekursif, untuk mendapatkan jalur absolut tautan. Sebagai contoh:

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

Jika melestarikan path relatif adalah apa yang Anda inginkan, daripada pilihan -Pdari cp, seperti yang dikatakan oleh Ignacio Vazquez-Abrams, adalah apa yang Anda butuhkan.


1
Mungkin merupakan ide yang buruk untuk melakukan dereferensi secara rekursif jika semua yang Anda coba lakukan adalah mengubah symlink dari relatif menjadi absolut. Rekursi tidak diperlukan di sini, dan terkadang symlink dirantai ada karena suatu alasan. Symlinks sering digunakan untuk menentukan opsi atau opsi konfigurasi. Sebagai contoh, pada sistem saya ada rantai symlink /usr/share/dict/words -> /etc/dictionaries-common/words -> /usr/share/dict/british-englishyang menentukan kamus pilihan. Jika Anda secara rekursif mereferensikan rantai ini, symlink yang dihasilkan akan mengabaikan perubahan apa pun di masa depan untuk preferensi ini.
James Haigh

24

Seperti beberapa yang berkomentar:

cp -a 

bekerja dengan baik.

Dari pria itu:

-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
... tetapi hanya jika tidak satu pun dari symlinks adalah jalur relatif.
Michael Scheper

11

Saya menggunakan yang berikut ini untuk menduplikasi direktori yang sangat besar. Semua tautan simbolis dilestarikan, salinannya dilakukan secara rekursif dan saya dapat memiliki beberapa umpan balik visual dari proses:

cp -Prv /sourcer_dir/* /target_dir

10

Sebagian besar waktu, ketika saya perlu menyalin banyak tautan simbolis, saya sebenarnya mencoba untuk mirror pohon direktori. Jadi saya ingin symlink dan yang lainnya.

Ini berlebihan untuk menyalin hanya beberapa symlink, tetapi jika Anda benar-benar mencoba menyalin seluruh pohon, ini bisa sangat berguna:

Gunakan tar .

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

tar tidak menyelesaikan symlink secara default, jadi symlink di salinan mirror akan menunjuk ke lokasi yang sama dengan yang di pohon asli.

Trik ini menggunakan subkulit untuk mendapatkan perintah tar ke posisi di root direktori yang akan dicerminkan; Anda dapat mengabaikan salah satunya (bersama dengan perintah cd yang terkait ) jika Anda sudah berada di direktori src atau 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 - )'

Sekali lagi, ini tidak sesuai untuk setiap kali Anda ingin menyalin tautan simbolis, tetapi ini adalah potongan yang sangat berguna untuk diketahui.


1
tar jelas lebih portabel daripada cp dalam pengalaman saya
don bright

4

Coba: cp -pr tujuan 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]# 

OS - Centos 5 (Linux)


3

Di Ubuntu saat menyalin tautan dan file di direktori:

cp --no-dereference --preserve=links

5
cp -dadalah singkatan untuk ini
hunse

1
Saya pikir keduanya cp -adan cp --preserve=linksmelakukan lebih dari pertanyaan yang diajukan. Seperti yang saya pahami, ini adalah jawaban yang benar untuk siapa pun yang menggunakan cp, meskipun hanya dengan file (tanpa direktori) seperti dalam pertanyaan, tidak --no-dereferenceakan berpengaruh.
palswim

2

Gunakan -Popsi, seperti yang ditulis Ignacio Vazquez-Abrams di atas . Apa yang tidak dia sebutkan adalah -Ptidak berpengaruh tanpa -R. Jadi, Anda setidaknya perlu cp -RP.

(Situs belum mengizinkan saya untuk berkomentar, jadi saya mengirim jawaban yang terpisah.)


Pada kotak solaris lama cp saya tidak mendukung -d. cp -rP bekerja untuk saya; (idk perbedaan antara -R dan -r, -r bekerja untuk saya).
spioter

1

cp -s dan cp -L adalah perintah khusus. Untuk kebutuhan Anda, jangan gunakan.

misalnya Menyalin direktori DIR yang berisi a dan tautan simbolik b yang menunjuk ke a.

  • cp -s DIR / * N / membuat tautan simbolik alih-alih menyalin, N / a -> ../ DIR / a (tautan) dan N / b -> (../ DIR / b) yang merupakan tautan ke tautan
  • cp -L DIR / * N / salinan dengan tautan referensi, N / a, N / b (sama dengan DIR / a)

Yang Anda butuhkan adalah N / a (= DIR / a), dan N / b -> ../ N / a; jadi salin saja tanpa dereferencing, menggunakan opsi cp -P. Saya percaya ini juga default untuk cp.

  • -P no-dereference, pertahankan tautan
  • -d menggabungkan opsi -P dengan -p untuk mempertahankan = mode, kepemilikan, cap waktu
  • -a menggabungkan opsi -d dengan -R untuk menyalin direktori secara rekursif

lihat man cpatau cp --helpuntuk lebih banyak opsi.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.