Comment copier la structure du répertoire sans supprimer les liens symboliques?

27

Je dois "installer" un tas de fichiers dans un autre répertoire en gardant intacte la structure de répertoires des fichiers source. Par exemple, si j'y ./foo/bar/baz.txtvais, /var/www/localhost/webroot/je veux que le résultat soit /var/www/localhost/webroot/foo/bar/baz.txt. rsynca cette capacité --relative, mais quand je l'ai fait, j'ai découvert qu'il n'était pas convivial pour les liens symboliques:

$ ls -ald /var/www/localhost/webroot/ | grep ^l
lrwxrwxrwx  1 www-data www-data     15 2014-01-03 13:45 media -> ../static/media
lrwxrwxrwx  1 root     root         13 2014-02-24 13:47 var -> ../static/var
$ rsync -qrR . /var/www/localhost/webroot/
$ ls -ald /var/www/localhost/webroot/ | grep var
drwxr-xr-x 3 root root 4096 2014-02-24 13:52 /var/www/localhost/webroot/var

Vous voyez donc que le lien symbolique n'est plus un lien symbolique - les fichiers ont été copiés au mauvais endroit!

rsynca également l' --no-implied-dirsoption, qui semble superficiellement faire ce que je veux, mais cela ne fonctionne que comme je le souhaite lorsque je ne fais pas de rsync récursif, donc je dois:

find . -type f -print0 | xargs -0I{} rsync -R --no-implied-dirs {} /var/www/localhost/webroot/

Existe-t-il un moyen plus direct d'accomplir cette mise en miroir de fichiers sans effacer les répertoires de liens symboliques intermédiaires (avec ou sans rsync)?

kojiro
la source

Réponses:

42

Utilisez rsyncl'option de -K( --keep-dirlinks). Depuis la page de manuel:

 -K, --keep-dirlinks
      This  option  causes  the  receiving side  to  treat  a
      symlink  to  a  directory  as though  it  were  a  real
      directory, but only if it matches a real directory from
      the  sender.   Without   this  option,  the  receiver’s
      symlink  would  be deleted  and  replaced  with a  real
      directory.

      For example, suppose you  transfer a directory foo that
      contains a file file, but foo is a symlink to directory
      bar  on  the  receiver.  Without  --keep-dirlinks,  the
      receiver  deletes  symlink  foo,   recreates  it  as  a
      directory,  and   receives  the   file  into   the  new
      directory.   With --keep-dirlinks,  the receiver  keeps
      the symlink and file ends up in bar.

      One note  of caution:  if you  use --keep-dirlinks, you
      must  trust all  the symlinks  in the  copy!  If  it is
      possible  for an  untrusted  user to  create their  own
      symlink to  any directory,  the user  could then  (on a
      subsequent  copy)  replace  the  symlink  with  a  real
      directory and affect the  content of whatever directory
      the  symlink references.   For backup  copies, you  are
      better off using something like a bind mount instead of
      a symlink to modify your receiving hierarchy.

      See also  --copy-dirlinks for  an analogous  option for
      the sending side.
angus
la source
16

Je voulais conserver mes liens symboliques en tant que liens symboliques. Pour cela, vous pouvez utiliser l'option -l.

    -l, --links                 copy symlinks as symlinks

Comme je copiais des frameworks sur OS X, j'ai trouvé cela utile.

Ben Flynn
la source
3

Veuillez utiliser -a, comme cela implique -lcomme cela était supposé ci-dessus. Mais il contient également d'autres options importantes si vous souhaitez une copie complète de la source.

Aussi: Si je comprends bien la page de manuel, -Kest destinée aux liens symboliques du côté récepteur. Je ne pense pas que cela devrait être la bonne réponse ici.

Christian Gut
la source
2

En tant que non- rsyncréponse, l' tarutilitaire peut effectuer cette tâche. Utilisez deux instances de tarchaque côté d'un canal, la première pour consommer une structure de répertoires et la seconde pour l'extraire ailleurs. La propriété du fichier de la copie changera probablement, tandis que les modes d'autorisation resteront probablement inchangés.

De nombreux exemples existent et j'ai trouvé les suggestions dans cette réponse assez rapidement: /unix//a/59108/34251 .

Modifier
Un deuxième exemple (plus succinct?): Https://unix.stackexchange.com/a/19824/34251 .

crw
la source