Escapezeichen in einem Remote-Pfad bei Verwendung von rsync über eine Remote-SSH-Verbindung

10

Wie können Sie Leerzeichen und dergleichen im Remote-Pfad umgehen, wenn Sie SSH verwenden, um rsync mit einem Remote-Server zu verbinden? Ein einfacher Backslash entgeht dem Leerzeichen für die lokale Bash-Eingabeaufforderung, aber auf dem Remotecomputer wird das Leerzeichen dann als Unterbrechung des Pfads gelesen, wodurch das Ende dieses Pfads markiert wird.

Wenn ich also tue rsync -avz /path/to/source/some\ dir/ [email protected]:/path/to/dest/some\ dir/, liest der Remote-Server dies als gerecht /path/to/dest/some/und da er dieses Ziel nicht aus der Ferne finden kann, weil das eigentliche Ziel "irgendein Verzeichnis" und nicht nur "irgendein" ist.

Wenn ich den gleichen Befehl versuche und dem Backslash und dem Leerzeichen entkomme, um die lokale Bash-Eingabeaufforderung zu umgehen und den Backslash für den Remote-Server beizubehalten (insgesamt drei Backslashes /path/to/dest/some\\\ dir/:), wird der Backslash zwar an den Remote-Server, aber an den Remote-Server gesendet dann interpretiert den Pfad als /path/to/dest/some\/anstatt /path/to/dest/some\ dir/noch den Raum und die Zeichen nach dem Strippen.

Wenn ich versuche, den Pfad in Anführungszeichen zu setzen, verhält es sich fast genauso und schneidet den Pfad an der Stelle effektiv ab. Es funktioniert also auch nur, um die lokale Bash-Eingabeaufforderung zu überwinden.

Ursprünglich verwendete ich einen Pfad, der ein "-" (Space-Hyphen-Space) -Segment enthielt, und der Remote-Server gab einen Fehler zurück, rsync: on remote machine: -: unknown optionder dieses ganze raumflüchtige Unterfangen überhaupt erst auslöste.

Was muss ich also tun, damit dies ordnungsgemäß mit dem Remote-Server funktioniert, ohne dass Leerzeichen oder andere fehlerhafte Zeichen wie Bindestriche aus dem Remote-Pfad entfernt werden müssen?

Purefusion
quelle
1
Versuchen Sie es mit einfachen und doppelten Anführungszeichen.
Jftuga
Javier erwähnte dies auch und es funktionierte schließlich, also habe ich mein Arbeitscodesegment in eine Antwort auf seine Antwort eingefügt.
Purefusion
@purefusion Markieren Sie die Antwort von Grégory als richtig. Das -sbehebt das Problem, ohne dass Double-Escape manuell angewendet werden muss.
m000

Antworten:

9

Baut auf dem Initiatorcomputer rsynceine Befehlszeile auf, die das rsync-Ziel auf dem Remotecomputer aufruft, und sendet diese Befehlszeile dann mit ssh .... als einzelne Zeichenfolge . Diese einzelne Zeichenfolge wird an die Shell übergeben, um sie zu analysieren, in Argumente aufzuteilen und auszuführen rsync. Ich habe keine Ahnung, warum das getan wird, anstatt die (bereits geteilten, erweiterten und nicht zitierten) Argumente in einen binärsicheren Container in den Remote-Rsync zu packen.

Das bedeutet, dass Ihre Argumente von zwei verschiedenen Shells analysiert werden , zitieren und entsprechend anfordern . Normalerweise umschließe ich jedes Argument mit doppelten Anführungszeichen und dann den gesamten Ausdruck mit einfachen Anführungszeichen. Manchmal reicht es nicht aus, oder es kann kompliziert sein, wenn derselbe Ausdruck lokal und remote verwendet werden soll.

In diesen Fällen setze ich normalerweise einige Softlinks mit einfachen ASCII-Namen ohne Leerzeichen und verwende diese.

Javier
quelle
8
Und der Gewinner ist ... einfache + doppelte Anführungszeichen! Vielleicht ist dies auf jedem Server anders. Wenn die anderen Antworten für einige Leute nicht funktionieren, wird dies vielleicht der Fall sein. Hier ist der erfolgreiche Code, den ich auf der Remote-Seite des Befehls rsync verwendet habe:'[email protected]:"/path/to/dest/some\ dir/"'
purefusion
Nun stellt sich die Frage, warum DIESES funktioniert (auf meinem Server), aber keine der anderen Optionen (nur den Pfad in doppelte Anführungszeichen setzen oder dreifache Backslashes verwenden). Ich verwende CentOS 5, wenn das wichtig ist.
Purefusion
Das sollte nicht nötig sein. Wie läuft es? Führen Sie es mit evaloder über einen Aufruf einer Funktion aus?
Mikel
Sie verwenden keine einfachen und doppelten Anführungszeichen. Sie verwenden einfache Anführungszeichen plus doppelte Anführungszeichen plus Backslash-Escapezeichen. Drei Zitierstufen. Dies sollte unnötig sein. Ich frage noch einmal: Wie läuft es ?
Mikel
@ Javier "Ich habe keine Ahnung warum das so ist". Vermutlich damit die Tildeexpansion funktioniert.
Mikel
2

Sie waren auf dem richtigen Weg, als Sie sagten:

Wenn ich den gleichen Befehl versuche und dem Backslash und dem Leerzeichen entkomme, um die lokale Bash-Eingabeaufforderung zu umgehen und den Backslash für den Remote-Server beizubehalten

Hier ist ein Weg, den ich am einfachsten finde:

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

und so funktioniert es auch.

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

Können Sie die genaue Ausgabe und eventuelle Fehler veröffentlichen?

Können Sie rsyncauf beiden Seiten durch ein Wrapper-Skript ersetzen ?

$ 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

Führen Sie dann Ihren rsync erneut aus, und es sollte beweisen, dass diese Art der Flucht funktioniert, z

Client-Seite:

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

Serverseite:

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

Im obigen Beispiel dir with spacesbesagt die Tatsache, dass das vierte Argument auf dem Server ( ) nur in einer Zeile steht, dass das Anführungszeichen ordnungsgemäß funktioniert.

Wenn dies nicht hilft, versuchen Sie erneut rsync -v, oder rsync -vv, oder rsync -vvv. Sie erhalten zusätzliche Debugging-Informationen.

Zwei andere dumme Vorschläge:

  • Ist der andere Server ein Linux-Server und wie lautet Ihre Standard-Shell dort?
    • Vielleicht werden Dateinamen anders erweitert als erwartet
  • Haben Sie vergessen, die Option -aoder hinzuzufügen -r?
    • Ich kann es nicht sagen, ohne Ihre Ausgabe zu sehen
Mikel
quelle
Wie in den Details der Frage erwähnt, habe ich tatsächlich beide Ihrer ersten beiden Methoden ausprobiert. Vielleicht funktionieren sie auf meinem Server einfach nicht. Ich hatte auch keine Lust, mit Wrapper-Skripten herumzuspielen. Ich versuche, mich vom Hacken von / usr / bin / ... fernzuhalten. Auf jeden Fall hat eine andere spezifischere Art des Zitierens tatsächlich für mich funktioniert, also ist es vielleicht nur mein Server, der sich so verhält. Ihre Vorschläge sind möglicherweise für Personen auf anderen Servern oder für Benutzer ohne CentOS durchaus realisierbar, wenn das Betriebssystem schließlich Teil des Problems ist.
Purefusion
Wie haben Sie es zitiert, damit es funktioniert?
Mikel
Sie lassen einige wichtige Details aus. Bitte geben Sie den tatsächlichen Befehl, den Sie ausführen, vollständig ein.
Mikel
2

Die Punktantwort:

Verwenden Sie -s (Schützen Sie Argumente) und setzen Sie Ihren Pfad in Anführungszeichen:

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

Funktioniert mit beiden Leerzeichen oder Bindestrichen.

Grégory Boddin
quelle
Vielen Dank! Dies ist eher eine geeignete Lösung als eine Problemumgehung.
m000
-2

Sie können Ihren Pfad einfach in Anführungszeichen setzen.

atx
quelle
1
Wie Sie vielleicht in den Details der Frage gesehen haben, habe ich dies tatsächlich bereits versucht. Eine andere Antwort schlug jedoch eine bestimmte Verwendung von Zitaten vor, und das funktionierte tatsächlich. :)
Purefusion
Sie benötigen beide Anführungszeichen und Backslashes.
Sridhar Sarnobat