2010-05-07 04:36:38 +0000 2010-05-07 04:36:38 +0000
188
188

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

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

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)

212
212
212
2010-05-07 05:02:45 +0000
cp --preserve=links

Из man-страницы:

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

Лично я использую cp -av для большей части моего тяжелого копирования. Таким образом, я могу сохранить все - даже рекурсивно - и увидеть результат. Конечно, это только личные предпочтения.

Что касается того, почему другие ваши варианты не сделали то, что вы ожидали, -s делает ссылку instead из копирования и -L идет по ссылкам в исходном тексте, чтобы найти файл для копирования, а не копировать сами ссылки.

47
47
47
2010-05-07 04:39:24 +0000

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

30
30
30
2010-05-07 05:09:01 +0000

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

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

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

24
24
24
2015-01-27 14:51:13 +0000

Как прокомментировали несколько человек:

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
11
11
11
2012-05-15 17:25:32 +0000

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

cp -Prv /sourcer_dir/* /target_dir
11
11
11
2010-05-07 06:03:32 +0000

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

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

Использовать tar.

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 - )'

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

4
4
4
2011-07-27 13:15:51 +0000

Попробуйте: cp -pr symlink destination

[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
3
3
2015-12-01 12:51:43 +0000

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

cp --no-dereference --preserve=links
2
2
2
2019-01-12 17:55:13 +0000

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

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

1
1
1
2018-06-26 03:24:57 +0000

cp -s и cp -L - это специальные команды. Для вашего требования используйте none.

, например, копирование каталога DIR, содержащего а и символическую ссылку 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 для preserve=mode,ownership,timestamps
  • -a объединяет опцию -d с опцией -R для рекурсивного копирования каталогов

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

Похожие вопросы

6
10
7
5
1