Come copiare i collegamenti simbolici?


180

Ho una directory che contiene alcuni collegamenti simbolici:

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

Devo copiarli nella directory corrente. I collegamenti risultanti dovrebbero essere indipendenti dai loro prototipi e condurre direttamente ai loro oggetti di destinazione.

  • cp -s crea collegamenti a collegamenti che non sono comportamenti appropriati.
  • cp -s -L si rifiuta di copiare i collegamenti alle directory
  • cp -s -L -r rifiuta di copiare i collegamenti relativi nella directory non funzionante

Cosa dovrei fare?


10
cp -dfatto il lavoro dalla mia parte.
m-ric

2
cp -Rsu un mac
Mirko

Risposte:


201
cp --preserve=links

Dalla pagina man:

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

Personalmente, lo uso cp -av per la maggior parte delle mie pesanti copie. In questo modo, posso preservare tutto, anche in modo ricorsivo, e vedere l'output. Certo, questa è solo una preferenza personale.

Sul motivo per cui le altre tue opzioni non hanno fatto ciò che ti aspettavi, -screa un collegamento anziché copiarlo e -Lsegue i collegamenti nell'origine per trovare il file da copiare invece di copiare i collegamenti stessi.


3
Potrebbe essere necessario aggiungere -R, perché altrimenti cp salterà le directory e i collegamenti simbolici alle directory.
Olivier 'Ölbaum' Scherler

8
Ho provato questo su Redhat e non funziona
Mansuro

41
su un Mac? usocp -a
Steve Tauber,

11
+1 per l' -aopzione. Heh, ho cercato cpinnumerevoli opzioni nella manpage della pagina innumerevoli volte, eppure devo aver sempre sfiorato questa. Fino ad ora ho usato -dpr, ma -acopre tutti quelli, oltre alla conservazione di un paio di altri attributi. Se avessi avuto bisogno di questi altri attributi avrei probabilmente cercato di nuovo l' --preserveopzione e usato -dr --preserve=all, che è esattamente quello che -aè! Beh, almeno lo so ora - -aè perfetto e questo è quello che userò d'ora in poi.
James Haigh,

3
Questo non ha funzionato su Cygwin. --preserve=linksnon era abbastanza. Diceva ancora cp: omitting directory. Ma ha -avfunzionato.
Chloe,

44

Proprio come dice la pagina man, usa -P.


8
su Mac -Pnon funziona su directory così ho usatocp -a
Steve Tauber

4
Grazie, ho visto e beneficiato della tua risposta 3 volte ora diverse volte nell'arco di un anno. Non riesco a ricordarlo!
Siddhartha,

Funziona, ma la mia pagina man dice "-P non segue mai i collegamenti simbolici in SOURCE", che non è intuitivamente lo stesso di "copia i collegamenti simbolici come collegamenti simbolici alla destinazione". ("non seguire mai" fa sembrare che funzioni in combinazione con -R)
RM

Questo a cp -Pdifferenza della risposta più votata da @kainosnous funziona per me. Grazie!
tommy.carstensen,

Funziona su Redhat. La risposta accettata non funziona!
Phiber,

29

Se i collegamenti contengono percorsi relativi, la copia del collegamento non regolerà il percorso relativo. Utilizzare readlink, con l'interruttore, -fper seguire in modo ricorsivo, al fine di ottenere il percorso assoluto del collegamento. Per esempio:

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

Se preservare i percorsi relativi è ciò che desideri, l'opzione -Pdi cp, come affermato da Ignacio Vazquez-Abrams, è ciò di cui hai bisogno.


1
Potrebbe essere una cattiva idea dereferenziare in modo ricorsivo se tutto ciò che stai cercando di fare è convertire i link simbolici dall'essere relativi all'assoluto. La ricorsione non è necessaria qui, e talvolta i collegamenti simbolici concatenati sono lì per un motivo. I collegamenti simbolici vengono spesso utilizzati per specificare scelte o opzioni di configurazione. Ad esempio, sul mio sistema esiste una catena di link simbolici /usr/share/dict/words -> /etc/dictionaries-common/words -> /usr/share/dict/british-englishche specifica il dizionario preferito. Se dovessi dereferenziare ricorsivamente questa catena, il link simbolico risultante ignorerebbe qualsiasi modifica futura a questa preferenza.
James Haigh,

24

Come alcuni hanno commentato:

cp -a 

funziona bene.

Dall'uomo:

-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
... ma solo se nessuno dei collegamenti simbolici riguarda percorsi relativi.
Michael Scheper,

11

Ho usato il seguente per duplicare una directory molto grande. Tutti i collegamenti simbolici sono stati conservati, la copia è stata eseguita in modo ricorsivo e sono stato in grado di avere un feedback visivo del processo:

cp -Prv /sourcer_dir/* /target_dir

10

Il più delle volte, quando ho bisogno di copiare molti collegamenti simbolici, in realtà sto provando a rispecchiare un albero di directory. Quindi voglio i symlink e tutto il resto.

Questo è eccessivo per la copia di alcuni symlink, ma se stai effettivamente cercando di copiare un intero albero, questo può essere molto utile:

Usa tar .

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

tar non risolve il collegamento simbolico di default, quindi i collegamenti simbolici nella copia speculare indicheranno le stesse posizioni di quelli nella struttura originale.

Questo trucco fa uso di subshells per mettere il comando tar in posizione nella radice della directory da speculare; puoi lasciarne uno fuori (insieme al comando cd associato ) se sei già nelle directory src o 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 - )'

Ancora una volta, questo non è appropriato per ogni volta che vuoi copiare collegamenti simbolici, ma è uno snippet molto utile da sapere.


1
tar è sicuramente più portatile di cp nella mia esperienza
don luminoso

4

Prova: cp -pr destinazione del link simbolico

[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]# 

Sistema operativo - Centos 5 (Linux)


3

Su Ubuntu quando si copiano collegamenti e file in una directory:

cp --no-dereference --preserve=links

5
cp -dè la scorciatoia per questo
hunse

1
Penso entrambi cp -ae cp --preserve=linksfaccio più di quanto la domanda si stia ponendo. A quanto ho capito, questa è la risposta corretta per chiunque utilizzi cp, anche se solo con i file (senza directory) come nella domanda, non --no-dereferenceavrebbe alcun effetto.
Palswim

2

Usa l' -Popzione, come ha scritto sopra Ignacio Vazquez-Abrams . Ciò di cui non ha parlato è che -Pnon ha alcun effetto senza -R. Quindi è necessario almeno cp -RP.

(Il sito non mi lascia ancora commentare, quindi ho pubblicato una risposta separata.)


Su una vecchia scatola di solaris il mio cp non supporta -d. cp -rP ha funzionato per me; (idk la differenza tra -R e -r, -r funziona per me).
spioter,

1

cp -s e cp -L sono comandi speciali. Per le tue esigenze, usa none.

ad es. copia di una directory DIR contenente a e un collegamento simbolico b che punta a a.

  • cp -s DIR / * N / crea un collegamento simbolico invece di copiare, N / a -> ../ DIR / a (collegamento) e N / b -> (../ DIR / b) che è un collegamento a un collegamento
  • cp -L DIR / * N / copie con link dereferencing, N / a, N / b (uguale a DIR / a)

Ciò di cui hai bisogno è N / a (= DIR / a) e N / b -> ../ N / a; quindi basta copiare senza dereferenziare, usando l'opzione cp -P. Credo che questo sia anche il valore predefinito per cp.

  • -P no-dereference, preserva i collegamenti
  • -d combina l'opzione -P con -p per preservare = modalità, proprietà, timestamp
  • -a combina l'opzione -d con -R per copiare ricorsivamente le directory

fare riferimento man cpo cp --helpper ulteriori opzioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.