Wie kopiere ich symbolische Links?

180

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 Verknüpfungen sollten unabhängig von ihren Prototypen sein und direkt zu ihren Zielobjekten führen.

  • cp -s Erstellt Verknüpfungen zu Verknüpfungen, die nicht dem entsprechenden Verhalten entsprechen.
  • 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 machen?

Basilevs
quelle
10
cp -dmachte den Job auf meiner Seite.
m-ric
2
cp -Rauf einem Mac
Mirko

Antworten:

201
cp --preserve=links

Von der Manpage:

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

Persönlich benutze ich cp -av für die meisten meiner schweren Kopieren. Auf diese Weise kann ich alles - auch rekursiv - beibehalten und die Ausgabe sehen. Das ist natürlich nur eine persönliche Präferenz.

Wie, warum Ihre andere Optionen tun nicht , was Sie erwartet haben , -smacht einen Link anstelle des Kopierens und -Lfolgt den Links in der Quelle , die Datei zu finden , sich selbst zu kopieren , anstatt die Links zu kopieren.

kainosnous
quelle
3
Möglicherweise müssen Sie hinzufügen -R, da cp sonst Verzeichnisse und Symlinks zu Verzeichnissen überspringt.
Olivier 'Ölbaum' Scherler
8
Ich habe es mit
Red Hat
41
auf einem Mac? Verwenden Siecp -a
Steve Tauber
11
+1 für die -aOption. Heh, ich habe cpunzählige Male in der Manpage nach Optionen gesucht , aber ich muss immer darüber nachgedacht haben. Ich habe bis jetzt verwendet -dpr, aber -aumfasst alle diese, sowie die Erhaltung von ein paar anderen Attributen. Wenn ich diese anderen Attribute gebraucht hätte, hätte ich die --preserveOption wahrscheinlich erneut gesucht und verwendet -dr --preserve=all, und genau das -aist es! Nun, zumindest weiß ich es jetzt - -aist perfekt und das ist es, was ich von nun an verwenden werde.
James Haigh
3
Bei Cygwin hat das nicht funktioniert. --preserve=linkswar nicht genug. Es sagte immer noch cp: omitting directory. Hat aber -avgeklappt.
Chloe
44

So wie der Mann Seite sagt, verwenden -P.

Ignacio Vazquez-Abrams
quelle
8
auf dem Mac -Pfunktioniert nicht auf Verzeichnissen, also habe ich verwendetcp -a
Steve Tauber
4
Vielen Dank, ich habe Ihre Antwort 3 Mal gesehen und profitiert, jetzt mehr als ein Jahr lang. Kann mich anscheinend nicht erinnern!
Siddhartha
Dies funktioniert, aber meine Manpage sagt "-P folgt niemals symbolischen Links in SOURCE", was nicht intuitiv mit "Symlinks als Symlinks zum Ziel kopieren" identisch ist. ("never follow" lässt es so klingen, als ob es in Kombination mit -R funktioniert)
RM
Dies cp -Pfunktioniert anders als die von @kainosnous oben gewählte Antwort für mich. Vielen Dank!
tommy.carstensen
Funktioniert mit Redhat. Die akzeptierte Antwort funktioniert nicht!
Phiber
29

Wenn die Links relative Pfade enthalten, wird durch das Kopieren des Links der relative Pfad nicht angepasst. Verwenden Sie readlinkmit dem Schalter -f, um rekursiv zu folgen, um den absoluten Pfad der Verknüpfung zu erhalten. Zum Beispiel:

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

Wenn Sie die relativen Pfade beibehalten möchten, ist die Option -Pvon cp, wie von Ignacio Vazquez-Abrams gesagt, die richtige.

Mrucci
quelle
1
Es kann eine schlechte Idee sein, rekursiv zu dereferenzieren, wenn Sie lediglich versuchen, Symlinks von relativ zu absolut zu konvertieren. Die Rekursion wird hier nicht benötigt, und manchmal gibt es verkettete Symlinks aus einem Grund. Symlinks werden häufig verwendet, um Auswahlmöglichkeiten oder Konfigurationsoptionen anzugeben. Auf meinem System gibt es beispielsweise eine Symlink-Kette, /usr/share/dict/words -> /etc/dictionaries-common/words -> /usr/share/dict/british-englishdie das bevorzugte Wörterbuch angibt. Wenn Sie diese Kette rekursiv dereferenzieren, ignoriert der resultierende Symlink alle zukünftigen Änderungen an dieser Präferenz.
James Haigh
24

Wie einige kommentiert 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
Juh_
quelle
3
... aber nur, wenn keiner der symbolischen Verweise auf relative Pfade verweist.
Michael Scheper
11

Ich habe Folgendes verwendet, um ein wirklich großes Verzeichnis zu duplizieren. Alle symbolischen Verknüpfungen wurden beibehalten, die Kopie wurde rekursiv erstellt und ich konnte einige visuelle Rückmeldungen zum Vorgang erhalten:

cp -Prv /sourcer_dir/* /target_dir
oarevalo
quelle
10

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

Dies ist zu viel des Guten, um nur ein paar Symlinks zu kopieren. Wenn Sie jedoch tatsächlich versuchen, einen ganzen Baum zu kopieren, kann dies sehr nützlich sein:

Verwenden Sie Teer .

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

tar löst den Symlink nicht standardmäßig auf, daher verweisen Symlinks in der Spiegelkopie auf dieselben Speicherorte wie die im ursprünglichen Baum.

Dieser Trick verwendet Subshells, um den Befehl tar im Stammverzeichnis des zu spiegelnden Verzeichnisses zu positionieren. Sie können einen davon (zusammen mit dem zugehörigen Befehl cd ) weglassen, wenn Sie sich bereits im Verzeichnis src oder dest 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 [email protected] '( cd /path/to/dest ; tar xf - )'

Auch dies ist nicht für jedes Mal geeignet, wenn Sie symbolische Links kopieren möchten, aber es ist ein sehr nützlicher Ausschnitt, den Sie kennen müssen.

Quacksalber
quelle
1
Meiner Erfahrung nach ist Teer definitiv tragbarer als CP
don bright
4

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)

ebe0
quelle
3

Unter Ubuntu beim Kopieren von Links und Dateien in ein Verzeichnis:

cp --no-dereference --preserve=links
Greg
quelle
5
cp -dist die Abkürzung dafür
hunse
1
Ich denke beides cp -aund cp --preserve=linksmache mehr als die Frage stellt. Soweit ich weiß, ist dies die richtige Antwort für jeden cp, der Dateien wie in der Frage verwendet (keine Verzeichnisse), --no-dereferencedie jedoch keine Wirkung haben würden.
Palswim
2

Benutze die -POption, wie Ignacio Vazquez-Abrams oben schrieb . Was er nicht erwähnt hat, -Phat keine Wirkung ohne -R. Also brauchst du wenigstens cp -RP.

(Auf der Website kann ich noch keine Kommentare abgeben, daher habe ich eine separate Antwort gepostet.)

1234ru
quelle
Auf einer alten Solaris-Box unterstützt mein cp -d nicht. CP-RP arbeitete für mich; (idk der Unterschied zwischen -R und -r, -r funktioniert für mich).
Spioter
1

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

zB Kopieren eines Verzeichnisses DIR mit a und einem symbolischen Link b, der auf a zeigt.

  • cp -s DIR / * N / erstellt eine symbolische Verknüpfung anstatt zu kopieren, N / a -> ../ DIR / a (Verknüpfung) und N / b -> (../ DIR / b), die eine Verknüpfung zu einer Verknüpfung darstellt
  • cp -L DIR / * N / Kopien 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 einfach ohne Dereferenzierung mit der Option cp -P. Ich glaube, das ist auch die Standardeinstellung für cp.

  • -P keine Dereferenzierung, Links erhalten
  • -d kombiniert die Option -P mit -p, um = Modus, Besitz, Zeitstempel beizubehalten
  • -a kombiniert die Option -d mit -R, um Verzeichnisse rekursiv zu kopieren

beziehen man cpoder cp --helpfür weitere Optionen.

Atif Hussain
quelle