Як скопіювати символічні посилання?


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
— Мірко

Відповіді:


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 буде пропускати каталоги та посилання на каталоги.
— Олів'є "Ельбаум" Шерлер

8
Я спробував це на redhat, і це не працює
— Мансуро

41
на Mac? використанняcp -a
— Стів Таубер

11
+1 для -aопції. Гей, я cpнезліченну кількість разів шукав варіанти , але я, мабуть, завжди переглядав цю. Я до сих пір використовую -dpr, але -aохоплює все це, а також збереження пари інших атрибутів. Якби мені були потрібні ці інші атрибути, я б, напевно, ще --preserveраз шукав варіант і використовував -dr --preserve=all, саме це -aє! Ну принаймні я зараз знаю - -aідеально, і це я буду використовувати зараз.
— Джеймс Хей

3
Це не спрацювало з Cygwin. --preserve=linksбуло недостатньо Ще сказано cp: omitting directory. Але -avпрацював.
— Хлоя

44

Так само, як каже сторінка man, використовуйте -P.


8
на Mac -Pне працює над каталогами, тому я використовувавcp -a
— Стів Таубер

4
Дякую, я бачив та отримав користь від вашої відповіді 3 рази в різні часи протягом року. Здається, не пам’ятаю це!
— Сіддхартха

Це працює, але на моїй сторінці man говорять "-P ніколи не слідкуйте за символічними посиланнями в ДЖЕРЕЛ", що не є інтуїтивно зрозумілим як "копіювати символьні посилання як символьні посилання на місце призначення". ("ніколи не слідкуйте" звучить так, як це працює в поєднанні з -R)
— RM

Це на cp -Pвідміну від голосової відповіді від @kainosnous працює для мене. Дякую!
— tommy.carstensen

Працює над Redhat. Прийнята відповідь не працює!
— Фібер

29

Якщо посилання містять відносні шляхи, то копіювання посилання не буде коригувати відносний шлях. Використовуйте readlinkза допомогою перемикача -fрекурсивно, щоб отримати абсолютний шлях посилання. Наприклад:

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

Якщо збереження відносних шляхів є те , що ви хочете, ніж варіант -Pз cp, як сказав Ігнасіо Васкес-Abrams, є те , що вам потрібно.


1
Може бути поганою ідеєю рекурсивної рекурсії, якщо все, що ви намагаєтеся зробити, це перетворити символьні посилання з відносних в абсолютні. Рекурсія тут не потрібна, а іноді прикуті символічні посилання є з причини. Символьні посилання часто використовуються для вказівки варіантів вибору або параметрів конфігурації. Наприклад, у моїй системі є ланцюг симпосилань, /usr/share/dict/words -> /etc/dictionaries-common/words -> /usr/share/dict/british-englishякий вказує кращий словник. Якби ви рекурсивно відтягували цей ланцюг, отримане символьне посилання ігнорувало б будь-які майбутні зміни цього параметра.
— Джеймс Хей

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
... але тільки якщо жодна із символьних посилань не має відносних шляхів.
— Майкл Шепер

11

Я використовував наступне, щоб дублювати дійсно великий каталог. Усі символічні посилання збереглися, копія була зроблена рекурсивно, і я мав можливість мати візуальні відгуки про процес:

cp -Prv /sourcer_dir/* /target_dir

10

Більшість часу, коли мені потрібно скопіювати багато символічних посилань, я насправді намагаюся відобразити дерево каталогів. Тож я хочу симлінки та все інше.

Це надмірне копіювання лише кількох символьних посилань, але якщо ви насправді намагаєтесь скопіювати ціле дерево, це може бути дуже корисно:

Використовуйте дьоготь .

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

tar не вирішує символьне посилання за замовчуванням, тому посилання в дзеркальній копії вказуватимуть на ті самі місця, що і в оригінальному дереві.

Цей трюк використовує допоміжні оболонки, щоб встановити команду 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
смола, безумовно, більш портативна, ніж CP в моєму досвіді
— нехай яскравий

4

Спробуйте: cp -pr, призначення символьного посилання

[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варіант, як писав вище Ігнасіо Васкес-Абрамс . Те, що він не згадував -P, без жодного ефекту -R. Тож вам потрібно як мінімум cp -RP.

(Сайт ще не дозволяє мені коментувати, тому я розмістив окрему відповідь.)


На старій коробці solaris мій процесор не підтримує -d. cp -rP працював на мене; (для мене працює idk різниці між -R і -r, -r).
— spioter

1

cp -s і cp -L - це спеціальні команди. Для вашої вимоги не використовуйте жодної.

наприклад, Копіювання DIR каталогу, що містить a, і символічне посилання b, що вказує на a.

  • 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.

  • -Перемежування, збереження посилань
  • -d поєднує параметр -P з -p для збереження = режим, право власності, часові позначки
  • -a поєднує -d варіант із -R для рекурсивного копіювання каталогів

див. man cpабо cp --helpдля отримання додаткових варіантів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.