Jak skopiować linki symboliczne?

180

Mam katalog, który zawiera niektóre dowiązania symboliczne:

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

Muszę je skopiować do bieżącego katalogu. Powstałe linki powinny być niezależne od ich prototypów i prowadzić bezpośrednio do ich obiektów docelowych.

  • cp -s tworzy linki do linków, które nie są właściwym zachowaniem.
  • cp -s -L odmawia kopiowania linków do katalogów
  • cp -s -L -r odmawia kopiowania względnych łączy do niedziałającego katalogu

Co powinienem zrobić?

Basilevs
źródło
10
cp -dwykonałem pracę po mojej stronie.
m-ric
2
cp -Rna komputerze Mac
Mirko

Odpowiedzi:

201
cp --preserve=links

Ze strony podręcznika:

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

Osobiście używam cp -av do większości moich ciężkich kopii. W ten sposób mogę zachować wszystko - nawet rekurencyjnie - i zobaczyć wyniki. Oczywiście to tylko osobiste preferencje.

Jeśli twoje inne opcje nie spełniły oczekiwań, -stworzy link zamiast kopiować i -Lpodąża za linkami w źródle, aby znaleźć plik do skopiowania zamiast kopiowania samych linków.

kainosnous
źródło
3
Może być konieczne dodanie -R, ponieważ w przeciwnym razie cp pominie katalogi i dowiązania symboliczne do katalogów.
Olivier 'Ölbaum' Scherler
8
Próbowałem tego na redhat i to nie działa
Mansuro
41
na komputerze Mac? użyciecp -a
Steve Tauber,
11
+1 dla -aopcji. Heh, szukałem opcji na stronie cpniezliczoną ilość razy, ale zawsze musiałem to omijać. Do tej pory używałem -dpr, ale -aobejmuje wszystkie te, a także zachowanie kilku innych atrybutów. Gdybym potrzebował tych innych atrybutów, prawdopodobnie ponownie sprawdziłbym tę --preserveopcję i użył jej -dr --preserve=all, a dokładnie to, co -ajest! Przynajmniej wiem teraz - -ajest idealny i od tej pory będę go używać.
James Haigh,
3
To nie działało na Cygwin. --preserve=linksnie wystarczyło. Nadal tak powiedział cp: omitting directory. Ale -avdziałało.
Chloe,
44

Tak jak mówi strona podręcznika, użyj -P.

Ignacio Vazquez-Abrams
źródło
8
na Macu -Pnie działa na katalogach, więc użyłemcp -a
Steve Tauber,
4
Dzięki, widziałem i skorzystałem z twojej odpowiedzi 3 razy teraz różne razy w ciągu roku. Nie mogę tego zapamiętać!
Siddhartha
To działa, ale moja strona podręcznika mówi: „-P nigdy nie podążaj za symbolicznymi linkami w ŹRÓDŁO”, co nie jest intuicyjnie takie samo jak „kopiuj dowiązania symboliczne jako dowiązania symboliczne do miejsca docelowego”. („nigdy nie podążaj” sprawia, że ​​brzmi to tak, jakby działało w połączeniu z -R)
RM
To w cp -Pprzeciwieństwie do najczęściej głosowanej odpowiedzi autorstwa @kainosnous działa dla mnie. Dzięki!
tommy.carstensen
Działa na Redhat. Akceptowana odpowiedź nie działa!
Phiber
29

Jeśli łącza zawierają ścieżki względne, wówczas skopiowanie łącza nie zmieni ścieżki względnej. Użyj readlinkprzełącznika, -faby śledzić rekurencyjnie, aby uzyskać bezwzględną ścieżkę łącza. Na przykład:

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

Jeśli zachowanie ścieżek względnych jest to, co chcesz, niż opcja -Pz cp, jak powiedział Ignacio Vazquez-Abrams, jest to, czego potrzebujesz.

mrucci
źródło
1
Wykluczanie rekurencyjne może być złym pomysłem, jeśli wszystko, co próbujesz zrobić, to przekonwertować dowiązania symboliczne z względnych na absolutne. Rekurencja nie jest tutaj potrzebna, a czasem powiązane linki dowiązań symbolicznych istnieją z jakiegoś powodu. Dowiązania symboliczne są często używane do określania opcji lub opcji konfiguracji. Na przykład w moim systemie istnieje łańcuch dowiązań symbolicznych, /usr/share/dict/words -> /etc/dictionaries-common/words -> /usr/share/dict/british-englishktóry określa preferowany słownik. Jeśli rekurencyjnie wyrejestrujesz ten łańcuch, powstałe dowiązanie symboliczne zignoruje wszelkie przyszłe zmiany tej preferencji.
James Haigh,
24

Jak kilku komentowało:

cp -a 

działa dobrze.

Od mężczyzny:

-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
Juh_
źródło
3
... ale tylko wtedy, gdy żadne z dowiązań symbolicznych nie prowadzi do ścieżek względnych.
Michael Scheper
11

Użyłem następujących do zduplikowania naprawdę dużego katalogu. Wszystkie dowiązania symboliczne zostały zachowane, kopia została wykonana rekurencyjnie i mogłem uzyskać wizualne informacje zwrotne na temat procesu:

cp -Prv /sourcer_dir/* /target_dir
oarevalo
źródło
10

Przez większość czasu, kiedy muszę skopiować wiele dowiązań symbolicznych, próbuję dublować drzewo katalogów. Chcę więc dowiązań symbolicznych i wszystkiego innego.

Jest to przesada w przypadku kopiowania tylko kilku dowiązań symbolicznych, ale jeśli faktycznie próbujesz skopiować całe drzewo, może to być bardzo przydatne:

Użyj tar .

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

tar domyślnie nie rozpoznaje dowiązania symbolicznego, więc dowiązania symboliczne w kopii lustrzanej będą wskazywać te same lokalizacje, co w oryginalnym drzewie.

Ta sztuczka wykorzystuje podpowłoki, aby ustawić komendę tar na pozycję w katalogu głównym katalogu, który ma być dublowany; możesz pominąć jeden z nich (wraz z powiązanym poleceniem cd ), jeśli już jesteś w katalogach src lub 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 [email protected] '( cd /path/to/dest ; tar xf - )'

Ponownie, nie jest to właściwe za każdym razem, gdy chcesz skopiować dowiązania symboliczne, ale jest to bardzo przydatny fragment.

quack quixote
źródło
1
smoła jest zdecydowanie bardziej przenośna niż cp z mojego doświadczenia
don bright
4

Spróbuj: cp -pr miejsce docelowe dowiązania symbolicznego

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

System operacyjny - Centos 5 (Linux)

ebe0
źródło
3

W systemie Ubuntu podczas kopiowania łączy i plików w katalogu:

cp --no-dereference --preserve=links
Greg
źródło
5
cp -djest skrótem od tego
hunse
1
Myślę, że jedno cp -ai drugie cp --preserve=linksrobią więcej niż pytanie. Rozumiem, że jest to poprawna odpowiedź dla każdego cp, kto używa , chociaż tylko pliki (bez katalogów) jak w pytaniu --no-dereferencenie miałyby żadnego efektu.
palswim
2

Użyj -Popcji, jak napisał Ignacio Vazquez-Abrams . To, o czym nie wspomniał, nie -Pma żadnego efektu -R. Więc potrzebujesz przynajmniej cp -RP.

(Witryna nie pozwala mi jeszcze komentować, więc opublikowałem osobną odpowiedź).

1234ru
źródło
Na starym pudełku solaris mój cp nie obsługuje -d. cp -rP działało dla mnie; (idk różnicę między -R i -r, -r działa dla mnie).
spioter
1

cp -s i cp -L to specjalne polecenia. Do swoich wymagań użyj none.

np. Skopiowanie katalogu DIR zawierającego a i dowiązanie symboliczne b wskazujące na a.

  • cp -s DIR / * N / tworzy dowiązanie symboliczne zamiast kopiowania, N / a -> ../ DIR / a (link) i N / b -> (../ DIR / b), który jest linkiem do linku
  • cp -L DIR / * N / kopie z dereferencją linków, nie dotyczy, nie dotyczy (to samo co DIR / a)

Potrzebujesz tylko N / a (= DIR / a), a N / b -> ../ N / a; więc po prostu skopiuj bez dereferencji, używając opcji cp -P. Wierzę, że jest to również domyślne ustawienie dla cp.

  • -P bez dereferencji, zachowaj linki
  • -d łączy opcję -P z opcją -p, aby zachować = tryb, własność, znaczniki czasu
  • -a łączy opcję -d z -R, aby rekurencyjnie kopiować katalogi

sprawdź man cplub cp --helpwięcej opcji.

Atif Hussain
źródło