Lorsque vous utilisez SSH pour connecter rsync à un serveur distant, comment échappez-vous aux espaces et autres dans le chemin distant? Une simple barre oblique inverse échappe à l'espace pour l'invite bash locale, mais sur la machine distante, l'espace est alors lu comme une interruption du chemin, marquant ainsi la fin de ce chemin.
Donc, quand je fais rsync -avz /path/to/source/some\ dir/ [email protected]:/path/to/dest/some\ dir/
ce qui se passe, c'est que le serveur distant lit cela comme juste /path/to/dest/some/
et puisqu'il ne peut pas trouver cette destination à distance, car la destination réelle est "certains dir" plutôt que simplement "certains".
Si j'essaye la même commande et échappe à la barre oblique inverse et à l'espace pour dépasser l'invite bash locale et maintenir la barre oblique inverse pour le serveur distant (trois barres obliques inversées au total:) /path/to/dest/some\\\ dir/
, cela envoie en effet la barre oblique inverse au serveur distant, mais au serveur distant interprète ensuite le chemin d'accès /path/to/dest/some\/
plutôt que de /path/to/dest/some\ dir/
supprimer l'espace et les caractères qui le suivent.
Si j'essaie de boucler le chemin avec des guillemets, il se comporte à peu près de la même manière, coupant efficacement le chemin dans l'espace. Donc, cela ne fonctionne que pour dépasser l'invite bash locale.
Au départ, j'utilisais un chemin qui contenait un segment "-" (espace-trait d'union-espace), et le serveur distant renvoyait une erreur rsync: on remote machine: -: unknown option
qui est à l'origine de cette tentative d'échapper à l'espace.
Alors, que dois-je faire pour que cela fonctionne correctement avec le serveur distant, sans avoir à supprimer les espaces ou autres caractères erronés comme les tirets du chemin distant?
-s
résout le problème sans qu'il soit nécessaire d'appliquer manuellement le double échappement.Réponses:
Sur la machine initiatrice,
rsync
crée une ligne de commande qui appelle la cible rsync sur la machine distante, puis envoie cette ligne de commande en utilisant ssh .... comme une seule chaîne . Cette chaîne unique est passée au shell pour être analysée, divisée en arguments et exécutéersync
. Je n'ai aucune idée pourquoi est-ce fait, au lieu d'emballer les arguments (déjà fractionnés, développés et non cités) dans un conteneur binaire sûr vers le rsync distant.Cela signifie que vos arguments seront analysés par deux coques différentes, citez et réévaluez en conséquence. Habituellement, j'encapsule chaque argument avec des guillemets doubles, puis l'expression entière sur des guillemets simples. parfois ce n'est pas suffisant, ou cela peut être compliqué si vous voulez que la même expression soit utilisée localement et à distance.
Dans ce cas, je définis généralement des liens logiciels avec des noms simples, sans espaces et entièrement ASCII, et je les utilise.
la source
'[email protected]:"/path/to/dest/some\ dir/"'
eval
ou via un appel à une fonction peut-être?Vous étiez sur la bonne voie lorsque vous avez dit:
Voici un moyen que je trouve le plus facile à faire:
et ça marche aussi.
Pouvez-vous publier la sortie exacte et les erreurs que vous voyez?
Pouvez-vous remplacer des
rsync
deux côtés un script wrapper?Ensuite, exécutez à nouveau votre rsync, et cela devrait prouver que cette façon de s'échapper fonctionne, par exemple
Côté client:
Du côté serveur:
Dans l'exemple ci-dessus, le fait que le 4ème argument sur le serveur (
dir with spaces
) se trouve sur une seule ligne indique que la citation fonctionne correctement.Si cela n'aide pas, essayez de relancer
rsync -v
, oursync -vv
, oursync -vvv
. Il vous donnera des informations de débogage supplémentaires.Deux autres suggestions idiotes:
-a
ou-r
?la source
La réponse de point:
Utilisez -s (protect args) et mettez votre chemin entre guillemets:
rsync -savz user@server:"/my path with spaces/another dir/" "/my destination/"
Fonctionne avec les deux espaces ou tirets.
la source
Vous pouvez simplement mettre votre chemin entre guillemets.
la source