Escaping degli spazi in un percorso remoto quando si utilizza rsync su una connessione SSH remota


10

Quando si utilizza SSH per connettere rsync a un server remoto, come si evitano spazi e simili nel percorso remoto? Una semplice barra rovesciata fuoriesce dallo spazio per il prompt di bash locale, ma sul computer remoto lo spazio viene quindi letto come un'interruzione nel percorso, segnando così la fine di quel percorso.

Quindi quando faccio rsync -avz /path/to/source/some\ dir/ user@host.tld:/path/to/dest/some\ dir/quello che succede è che il server remoto lo sta leggendo come giusto /path/to/dest/some/e poiché non riesce a trovare quella destinazione da remoto, perché la destinazione effettiva è "qualche dir" piuttosto che solo "un po '".

Se provo lo stesso comando ed esco dalla barra rovesciata e dallo spazio per superare il prompt bash locale e mantenere la barra rovesciata per il server remoto (tre barre rovesciate in totale:) /path/to/dest/some\\\ dir/, in effetti invia la barra rovesciata al server remoto, ma al server remoto quindi interpreta il percorso come /path/to/dest/some\/piuttosto che /path/to/dest/some\ dir/spogliare ancora lo spazio e i personaggi dopo di esso.

Se provo a racchiudere il percorso tra virgolette, si comporta praticamente allo stesso modo, tagliando efficacemente il percorso nello spazio. Quindi funziona anche solo per superare il prompt bash locale.

Inizialmente stavo usando un percorso che conteneva un segmento "-" (spazio-trattino-spazio), e il server remoto stava restituendo un errore rsync: on remote machine: -: unknown optionche è ciò che ha dato il via a tutto questo sforzo di fuga dallo spazio.

Quindi cosa devo fare per farlo funzionare correttamente con il server remoto, senza dover rimuovere gli spazi o altri caratteri errati come trattini dal percorso remoto?


1
Prova le virgolette singole e doppie.
jftuga,

Anche Javier ne ha parlato e alla fine ha funzionato, quindi ho incollato il mio segmento di codice funzionante in una risposta alla sua risposta.
purefusion,

@purefusion Valuta di contrassegnare la risposta di Grégory come corretta. Gli -sindirizzi il problema senza la necessità di applicare doppio fuga manualmente.
m000,

Risposte:


9

Sulla macchina iniziatore, rsynccrea una riga di comando che richiama la destinazione rsync sulla macchina remota, quindi invia quella riga di comando usando ssh .... come una singola stringa . Quella singola stringa viene passata alla shell per essere analizzata, suddivisa in argomenti ed eseguita rsync. Non ho idea del perché sia ​​fatto, invece di impacchettare gli argomenti (già suddivisi, espansi e non quotati) in qualche contenitore binario sicuro al rsync remoto.

Ciò significa che i tuoi argomenti saranno analizzati da due diverse shell, citando e requote di conseguenza. Di solito, avvolgo ogni argomento con virgolette doppie, quindi l'intera espressione su virgolette singole. a volte non è sufficiente o può essere complicato se si desidera utilizzare la stessa espressione in locale e in remoto.

In questi casi, di solito imposto alcuni soft link con nomi semplici, senza spazi, tutti ASCII e li uso.


8
E il vincitore è ... virgolette singole + doppie! Forse questo è diverso su ogni server, quindi se le altre risposte non funzionano per alcune persone, forse questa funzionerà. Ecco il codice di successo che ho usato sul lato remoto del comando rsync:'user@host.tld:"/path/to/dest/some\ dir/"'
purefusion,

Ora pone la domanda, perché QUESTO funziona (sul mio server), ma non una delle altre opzioni (semplicemente racchiudendo il percorso tra virgolette doppie o usando le barre rovesciate triple)? Sto usando CentOS 5 se questo è importante.
purefusion,

Non dovrebbe essere necessario. Come lo stai eseguendo? Lo stai eseguendo utilizzando evalo tramite una chiamata a una funzione forse?
Mikel,

Non stai usando virgolette singole più doppie. Stai utilizzando virgolette singole più virgolette doppie e escape di barra rovesciata. TRE livelli di quotazione. Questo non dovrebbe essere necessario. Chiedo di nuovo: come lo stai eseguendo ?
Mikel,

@Javier "Non ho idea del perché sia ​​fatto". Presumibilmente in modo che l'espansione della tilde funzioni.
Mikel,

2

Eri sulla strada giusta quando hai detto:

Se provo lo stesso comando ed esco dalla barra rovesciata e dallo spazio per superare il prompt di bash locale e mantenere la barra rovesciata per il server remoto

Ecco un modo per trovare più semplice farlo:

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

e anche in questo modo funziona.

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

Puoi pubblicare l'output esatto e gli eventuali errori che vedi?

È possibile sostituire rsyncsu entrambi i lati con uno script 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

Quindi esegui di nuovo rsync e dovrebbe dimostrare che questo modo di scappare funziona, ad es

Dalla parte del cliente:

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

Lato server:

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

Nell'esempio sopra, il fatto che il quarto argomento sul server ( dir with spaces) sia tutto su una riga indica che la quotazione funziona correttamente.

Se questo non aiuta, prova a rieseguire rsync -v, o rsync -vv, o rsync -vvv. Ti fornirà ulteriori informazioni di debug.

Altri due stupidi suggerimenti:

  • l'altro server è un server Linux e qual è la tua shell predefinita lì?
    • forse sta espandendo i nomi dei file in modo diverso da quello che ti aspetti
  • hai dimenticato di aggiungere l' opzione -ao -r?
    • Non posso dirlo senza vedere il tuo risultato

Come menzionato nei dettagli della domanda, ho davvero provato entrambi i tuoi primi due metodi. Forse non funzionano sul mio server. Inoltre non avevo voglia di scherzare con gli script wrapper. Cerco di stare lontano dall'hacking di / usr / bin / ... In ogni caso, un altro modo più specifico di quotare ha davvero funzionato per me, quindi forse è solo il mio server che agisce in questo modo. I tuoi suggerimenti potrebbero comunque essere fattibili per le persone su altri server, o per quelli che non eseguono CentOS, se il sistema operativo dopo tutto è parte del problema.
purefusion,

Quindi, come lo hai citato per farlo funzionare?
Mikel,

Stai tralasciando alcuni dettagli vitali. Si prega di inviare il comando effettivo che si sta eseguendo, per intero.
Mikel,

2

Il punto risponde:

Usa -s (protect args) e racchiudi il tuo percorso tra virgolette:

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

Funziona con spazi o trattini.


Grazie! Questa è una soluzione adeguata, piuttosto che una soluzione alternativa.
m000,

-2

Puoi racchiudere il tuo percorso tra virgolette.


1
Come avrai visto nei dettagli della domanda, in effetti l'ho già provato. Tuttavia, un'altra risposta ha suggerito l'uso specifico del preventivo, e alla fine ha funzionato. :)
purefusion,

Hai bisogno di ENTRAMBI virgolette e barre rovesciate.
Sridhar Sarnobat,
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.