Escapando espaços em um caminho remoto ao usar o rsync em uma conexão SSH remota

10

Ao usar o SSH para conectar o rsync a um servidor remoto, como você evita espaços e outras coisas no caminho remoto? Uma barra invertida simples escapa do espaço para o prompt do bash local, mas na máquina remota o espaço é lido como uma interrupção no caminho, marcando assim o final desse caminho.

Então, quando eu faço o rsync -avz /path/to/source/some\ dir/ [email protected]:/path/to/dest/some\ dir/que acontece, o servidor remoto está lendo isso como justo /path/to/dest/some/e uma vez que não consegue encontrar esse destino remotamente, porque o destino real é "alguns dir" em vez de apenas "alguns".

Se eu tentar o mesmo comando e escapar da barra invertida e do espaço para passar pelo prompt do bash local e manter a barra invertida do servidor remoto (três barras invertidas no total :) /path/to/dest/some\\\ dir/, ela enviará a barra invertida para o servidor remoto, mas o servidor remoto depois interpreta o caminho como /path/to/dest/some\/ao invés de /path/to/dest/some\ dir/ainda remover o espaço e os caracteres após ele.

Se eu tentar quebrar o caminho com aspas, ele se comportará da mesma maneira, cortando efetivamente o caminho no espaço. Por isso, também funciona apenas para passar pelo prompt do bash local.

Inicialmente, eu estava usando um caminho que continha um segmento "-" (espaço-hífen-espaço) e o servidor remoto estava retornando um erro rsync: on remote machine: -: unknown optionque foi o que deu início a todo esse esforço de escape de espaço.

Então, o que devo fazer para que isso funcione corretamente com o servidor remoto, sem precisar remover os espaços ou outros caracteres incorretos, como hífens, do caminho remoto?

purefusion
fonte
1
Tente aspas simples e duplas.
jftuga
Javier também mencionou isso, e acabou funcionando, então colei meu segmento de código de trabalho em uma resposta à sua resposta.
purefusion
@purefusion Considere marcar a resposta de Grégory como correta. O -sproblema é resolvido sem a necessidade de aplicar escape duplo manualmente.
m000 27/02

Respostas:

9

Na máquina do iniciador, rsynccria uma linha de comando que chama o destino rsync na máquina remota e envia essa linha de comando usando ssh .... como uma única sequência . Essa única cadeia é passada ao shell para analisar, dividir em argumentos e executar rsync. Eu não tenho idéia do por que isso foi feito, em vez de empacotar os argumentos (já divididos, expandidos e sem aspas) em algum contêiner de segurança binária no rsync remoto.

Isso significa que seus argumentos serão analisados ​​por duas conchas diferentes, citar e refazer de acordo. Normalmente, envolvo cada argumento entre aspas duplas e, em seguida, toda a expressão entre aspas simples. às vezes, não é suficiente ou pode ser complicado se você deseja que a mesma expressão seja usada local e remotamente.

Nesses casos, geralmente defino alguns links simples com nomes simples, sem espaços e todos ASCII, e utilizo isso.

Javier
fonte
8
E o vencedor é ... aspas simples e duplas! Talvez isso seja diferente em todos os servidores; portanto, se as outras respostas não funcionarem para algumas pessoas, talvez essa funcione. Aqui está o código de sucesso que eu usei no lado remoto do comando rsync:'[email protected]:"/path/to/dest/some\ dir/"'
purefusion
Agora, a pergunta é: por que ISTO funciona (no meu servidor), mas não uma das outras opções (apenas encapsulando o caminho entre aspas duplas ou usando barras invertidas triplas)? Estou executando o CentOS 5, se isso importa.
Purefusion
Isso não deveria ser necessário. Como você está executando isso? Você está executando usando evalou através de uma chamada para uma função, talvez?
Mikel
Você não está usando aspas simples e duplas. Você está usando aspas simples, aspas duplas e escapes de barra invertida. TRÊS níveis de cotação. Isso deve ser desnecessário. Eu pergunto novamente: como você está executando ?
Mikel
@Javier "Eu não tenho idéia do por que isso é feito". Presumivelmente, para que a expansão do til funcione.
Mikel
2

Você estava no caminho certo quando disse:

Se eu tentar o mesmo comando e escapar da barra invertida e do espaço para passar pelo prompt local do bash e manter a barra invertida do servidor remoto

Aqui está uma maneira que eu acho mais fácil:

rsync -av dir\ with\ spaces/ server.tld:"dir\ with\ spaces"

e dessa maneira funciona também.

rsync -av dir\ with\ spaces/ server.tld:dir\\\ with\\\ spaces

Você pode postar a saída exata e os erros que está vendo?

Você pode substituir rsyncnos dois lados por um script de wrapper?

$ sudo su -
# cd /usr/bin
# mv rsync rsync.real
# cat <<'EOF' >rsync
#!/bin/bash
logfile=/home/yourname/rsync.log
date >> "$logfile"
i=1
for arg in "$@"; do
    echo "arg $i: $arg" >> "$logfile"
    i=$((i+1))
done

rsync.real "$@"
EOF
# chmod +x rsync

Em seguida, execute o seu rsync novamente e deve provar que essa maneira de escapar funciona, por exemplo,

Lado do cliente:

Sun Feb 13 13:48:12 EST 2011
1: -av
2: dir with spaces/
3: server:dir\ with\ spaces

Lado do servidor:

Sun Feb 13 13:48:13 EST 2011
1: --server
2: -vlogDtpre.iL
3: .
4: dir with spaces

No exemplo acima, o fato de o quarto argumento no servidor ( dir with spaces) estar em uma linha indica que a citação está funcionando corretamente.

Se isso não ajudar, tente executar novamente rsync -v, ou rsync -vv, ou rsync -vvv. Ele fornecerá informações extras sobre depuração.

Duas outras sugestões tolas:

  • o outro servidor é um servidor Linux e qual é o seu shell padrão?
    • talvez esteja expandindo nomes de arquivos de maneira diferente do que você espera
  • você esqueceu de adicionar a opção -aou -r?
    • Eu não posso dizer sem ver sua saída
Mikel
fonte
Como mencionado nos detalhes da pergunta, tentei de fato os dois primeiros métodos. Talvez eles simplesmente não funcionem no meu servidor. Eu também não estava com vontade de mexer com scripts de wrapper. Eu tento evitar hackers no / usr / bin / ... De qualquer forma, outra maneira mais específica de citar realmente funcionou para mim, então talvez seja apenas o meu servidor que está agindo dessa maneira. Suas sugestões ainda podem certamente ser viáveis ​​para pessoas em outros servidores, ou aqueles que não executam o CentOS, se o SO for parte do problema, afinal.
purefusion
Então, como você citou para fazer funcionar?
Mikel
Você está deixando de fora alguns detalhes vitais. Por favor, poste o comando real que você está executando, na íntegra.
Mikel
2

A resposta do ponto:

Use -s (proteja os argumentos) e coloque seu caminho entre aspas:

rsync -savz user@server:"/my path with spaces/another dir/" "/my destination/"

Funciona com espaços ou traços.

Grégory Boddin
fonte
Obrigado! Esta é uma solução adequada, e não uma solução alternativa.
m000 27/02
-2

Você pode apenas colocar seu caminho entre aspas.

atx
fonte
1
Como você deve ter visto nos detalhes da pergunta, eu realmente já tentei isso. No entanto, outra resposta sugeriu o uso de cotações específicas, e isso realmente acabou funcionando. :)
purefusion
Você precisa de duas aspas e barras invertidas.
Sridhar Sarnobat