it-swarm-ru.tech

Как скопировать символические ссылки?

У меня есть каталог, который содержит несколько символических ссылок:

[email protected]: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 отказывается копировать относительные ссылки в нерабочий каталог

Что я должен делать?

173
Basilevs
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 следует по ссылкам в источнике, чтобы найти файл для копирования вместо копирования самих ссылок.

193
kainosnous

Как написано в справочной странице, используйте -P.

39
Ignacio Vazquez-Abrams

Если ссылки содержат относительные пути, то копирование ссылки не будет корректировать относительный путь. Используйте readlink, с ключом -f для рекурсивного следования, чтобы получить абсолютный путь ссылки. Например:

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

Если вы хотите сохранить относительные пути, то вам нужна опция -P из cp, как сказал Игнасио Васкес-Абрамс.

28
mrucci

Как некоторые прокомментировали:

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
23
Juh_

В большинстве случаев, когда мне нужно скопировать много символических ссылок, я на самом деле пытаюсь отразить дерево каталогов. Поэтому я хочу символические ссылки и все остальное.

Это избыточно для копирования всего нескольких символических ссылок, но если вы на самом деле пытаетесь скопировать целое дерево, это может быть очень полезно:

Используйте tar .

[email protected]:/cwd$ ( cd /path/to/src ; tar cf - . ) | ( cd /path/to/dest ; tar xf - )

tar не разрешает символическую ссылку по умолчанию, поэтому символические ссылки в зеркальной копии будут указывать на те же местоположения, что и в исходном дереве.

Этот прием использует подоболочки для перевода команды tar в корень каталога, который нужно отразить; Вы можете оставить один из них (вместе со связанной командой cd ), если вы уже находитесь в каталогах src или dest :

# already in src?
[email protected]:/src$ tar cf - . | ( cd /path/to/dest ; tar xf - )

# already in dest?
[email protected]:/dest$ ( cd /path/to/src ; tar cf - . ) | tar xf - 

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

# mirror to another system?
[email protected]:/src$ tar cf - . | ssh [email protected] '( cd /path/to/dest ; tar xf - )'

Опять же, это не подходит для каждого случая, когда вы хотите скопировать символические ссылки, но это очень полезный фрагмент кода.

10
quack quixote

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

cp -Prv /sourcer_dir/* /target_dir
10
oarevalo

Попробуйте: cp -pr назначение символической ссылки

[[email protected] 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
[[email protected] temp]# cp -rp /tmp/temp/abc.link1 /tmp/temp/abc.link2
[[email protected] 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
[[email protected] temp]# 

ОС - Centos 5 (Linux)

4
ebe0

В Ubuntu при копировании ссылок и файлов в каталог:

cp --no-dereference --preserve=links
3
Amiramix

Используйте опцию -P, как Игнасио Васкес-Абрамс писал выше . То, что он не упомянул, это -P не имеет никакого эффекта без -R. Так что вам нужен хотя бы cp -RP.

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

1
1234ru

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.

  • -P без разыменования, сохранить ссылки
  • -d объединяет опцию -P с -p для сохранения = режим, владение, метки времени
  • -a объединяет опцию -d с -R для рекурсивного копирования каталогов

обратитесь к man cp или cp --help для получения дополнительных опций.

1
Atif Hussain