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

Wie kopiert man symbolische Links?

Ich habe ein Verzeichnis, das einige symbolische Links enthält:

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

Ich muss sie in das aktuelle Verzeichnis kopieren. Die resultierenden Links sollten unabhängig von ihren Prototypen sein und direkt zu ihren Zielobjekten führen.

  • cp -s erstellt Links zu Links, was nicht angemessenes Verhalten ist.
  • cp -s -L weigert sich, Links zu Verzeichnissen zu kopieren.
  • cp -s -L -r weigert sich, relative Links in ein nicht funktionierendes Verzeichnis zu kopieren.

Was soll ich tun?

Antworten (10)

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

Aus der Man Page:

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

Ich persönlich benutze cp -av für die meisten meiner schweren Kopien. Auf diese Weise kann ich alles - auch rekursiv - erhalten und die Ausgabe sehen. Natürlich ist das nur eine persönliche Vorliebe.

Warum Ihre anderen Optionen nicht das taten, was Sie erwartet hatten: -s erstellt einen Link anstelle des Kopierens und -L folgt den Links in der Quelle, um die zu kopierende Datei zu finden, anstatt die Links selbst zu kopieren.

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

Genau wie in der Man Page steht, verwenden Sie -P.

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

Wenn die Links relative Pfade enthalten, wird der relative Pfad beim Kopieren des Links nicht angepasst. Verwenden Sie readlink, mit dem Schalter -f, um rekursiv zu folgen, um den absoluten Pfad des Links zu erhalten. Zum Beispiel:

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

Wenn Sie die relativen Pfade beibehalten wollen, dann ist die Option -P von cp, wie Ignacio Vazquez-Abrams sagte, das, was Sie brauchen.

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

Wie einige wenige bemerkt haben:

cp -a

funktioniert gut.

Vom Mann:

-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

Ich habe das Folgende verwendet, um ein wirklich großes Verzeichnis zu duplizieren. Alle symbolischen Links blieben erhalten, die Kopie erfolgte rekursiv, und ich konnte eine visuelle Rückmeldung über den Vorgang erhalten:

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

Die meiste Zeit, wenn ich viele symbolische Links kopieren muss, versuche ich eigentlich, einen Verzeichnisbaum zu spiegeln. Also möchte ich die Symlinks und alles andere.

Das ist ein Overkill für das Kopieren von nur ein paar Symlinks, aber wenn Sie tatsächlich versuchen, einen ganzen Baum zu kopieren, kann das sehr nützlich sein:

Benutzen Sie tar.

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

tar löst den Symlink nicht standardmäßig auf, so dass die Symlinks in der Spiegelkopie auf die gleichen Stellen zeigen wie die im Originalbaum.

Dieser Trick nutzt Sub-Shells, um den tar-Befehl an die Wurzel des zu spiegelnden Verzeichnisses zu bringen; Sie können einen davon weglassen (zusammen mit dem zugehörigen cd-Befehl), wenn Sie sich bereits in den src- oder dest-Verzeichnissen befinden:

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

Nochmals, dies ist nicht jedes Mal angebracht, wenn Sie symbolische Links kopieren wollen, aber es ist ein sehr nützlicher Schnipsel, den Sie kennen sollten.

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

Versuchen Sie: 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

Auf Ubuntu beim Kopieren von Links und Dateien in einem Verzeichnis:

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

Verwenden Sie die Option -P, wie Ignacio Vazquez-Abrams oben schrieb. Was er nicht erwähnt hat, ist, dass -P ohne -R keine Wirkung hat. Man braucht also mindestens cp -RP.

(Die Seite lässt mich noch keine Kommentare abgeben, also habe ich eine separate Antwort gepostet).

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

cp -s und cp -L sind spezielle Befehle. Verwenden Sie für Ihre Anforderung keine.

z.B. Kopieren eines Verzeichnisses DIR, das a und einen symbolischen Link b enthält, der auf a zeigt.

  • cp -s DIR/* N/ erzeugt einen symbolischen Link anstatt zu kopieren, N/a->../DIR/a (Link) und N/b->(. ./DIR/b), das ein Link zu einem Link ist
  • cp -L DIR/* N/ kopiert mit Link-Dereferenzierung, N/a, N/b (wie DIR/a)

Was Sie brauchen, ist N/a(=DIR/a), und N/b->../N/a; kopieren Sie also einfach ohne Dereferenzierung mit der Option cp -P. Ich glaube, dies ist auch die Voreinstellung für cp.

  • - -P no-dereference, preserve links
  • -d kombiniert die Option -P mit -p, um preserve=mode,ownership,timestamps zu erhalten
  • - -a kombiniert die Option -d mit -R, um Verzeichnisse rekursiv zu kopieren

verweist auf man cp oder cp --help für weitere Optionen.