web-dev-qa-db-fra.com

rsync - créer tous les répertoires parents manquants?

Je cherche un programme semblable à rsync qui créera tous les répertoires parents manquants du côté distant.

Par exemple, si j'ai /top/a/b/c/d sur un serveur et seulement /top/a existe sur le serveur distant, je souhaite copier d sur le serveur distant et créer également les répertoires b et c.

La commande:

rsync /top/a/b/c/d remote:/top/a/b/c

ne fonctionnera pas car /tmp/a/b n'existe pas sur le serveur distant. Et s'il existait, le fichier d serait copié dans le chemin /top/a/b/c.

Cela est possible avec rsync en utilisant --include et --exclude commutateurs, mais il est très impliqué, par exemple:

rsync -v -r a dest:dir  \
  --include 'a/b'       \
  --include 'a/b/c'     \
  --include 'a/b/c/d'   \
  --include 'a/b/c/d/e' \
  --exclude 'a/*'       \
  --exclude 'a/b/*'     \
  --exclude 'a/b/c/*'   \
  --exclude 'a/b/c/d/*' 

ne copiera que a/b/c/d/e à dest:dir/a/b/c/d/e même si les répertoires intermédiaires ont des fichiers. (Remarque - les inclus doivent précéder les exclus.)

Il y a-t-il des alternatives?

36
ErikR

Vous cherchez peut-être

rsync -aR

par exemple:

rsync -a --relative /top/a/b/c/d remote:/

Voir aussi cette astuce dans autre question .

18
Balu
rsync -aq --rsync-path='mkdir -p /tmp/imaginary/ && rsync' file user@remote:/tmp/imaginary/

De http://www.schwertly.com/2013/07/forcing-rsync-to-create-a-remote-path-using-rsync-path/ , mais ne copiez pas et ne collez pas à partir de là, sa syntaxe est massacrée.

il vous permet d'exécuter une commande arbitraire pour configurer le chemin des exécutables rsync.

13
Eddie

je suggère que vous imposiez l'existence manuellement:

ssh user@remote mkdir -p /top/a/b/c
rsync /top/a/b/c/d remote:/top/a/b/c

cela crée le dossier cible s'il n'existe pas déjà.

7
mnagel

Selon https://unix.stackexchange.com/a/496181/578 , depuis rsync 2.6.7, --relative fonctionne si vous utilisez . pour ancrer le répertoire parent de départ à créer à la destination:

derek@DESKTOP-2F2F59O:~/projects/rsync$ mkdir --parents top1/a/b/c/d
derek@DESKTOP-2F2F59O:~/projects/rsync$ mkdir --parents top2/a
derek@DESKTOP-2F2F59O:~/projects/rsync$ rsync --recursive --relative --verbose top1/a/./b/c/d top2/a/
sending incremental file list
b/
b/c/
b/c/d/

sent 99 bytes  received 28 bytes  254.00 bytes/sec
total size is 0  speedup is 0.00
1
Derek Mahar

Je cherchais une meilleure solution, mais la mienne semble mieux adaptée lorsque vous avez trop de sous-répertoires pour les créer manuellement.

Utilisez simplement cp comme étape intermédiaire avec le --parents option

cp --parents /your/path/sub/dir/ /tmp/localcopy
rsync [options] /tmp/localcopy/* remote:/destination/path/

cp --parents créera la structure pour vous.

Vous pouvez l'appeler à partir de n'importe quel sous-dossier si vous souhaitez copier un seul sous-ensemble des dossiers parents.

1
jesseme

--relative ne fonctionne pas pour moi car j'avais une configuration différente. Peut-être que je ne comprenais tout simplement pas comment --relative fonctionne, mais j'ai trouvé que le

ssh remote mkdir -p /top/a/b/c
rsync /top/a/b/c/d remote:/top/a/b/c

est facile à comprendre et fait le travail.

1
andrej