Escaping spaces in a remote path when using rsync over a remote SSH connection

On the initiator machine, rsync builds up a command line that invokes the rsync target on the remote machine, then sends that command line using ssh.... as a single string. That single string is passed to the shell to parse, split into arguments and execute rsync. I have no idea why is that done, instead of packing the (already splitted, expanded and unquoted) arguments in some binary-safe container to the remote rsync.

That means that your arguments will be parsed by two different shells, quote and requote accordingly. Usually, I wrap each argument with double-quotes, and then the whole expression on single-quotes. sometimes it's not enough, or it can be complicated if you want the same expression to be used locally and remotely.

In that cases, I usually set some soft links with simple, no-spaces, all-ASCII names, and use that.


You were on the right track when you said:

If I try the same command and escape the backslash and the space to get past the local bash prompt and maintain the backslash for the remote server

Here's a way I find easiest to do it:

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

and this way works as well.

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

Can you post the exact output and any errors you're seeing?

Can you replace rsync on both sides with a wrapper script?

$ 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

Then run your rsync again, and it should prove that this way of escaping works, e.g.

Client side:

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

Server side:

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

In the above example, the fact that the 4th argument on the server (dir with spaces) is all on one line says that the quoting is working correctly.

If this doesn't help, try re-running rsync -v, or rsync -vv, or rsync -vvv. It will give you extra debugging information.

Two other silly suggestions:

  • is the other server a Linux server, and what is your default shell there?
    • maybe it is expanding file names differently than you expect
  • did you forget to add the -a or -r option?
    • I can't tell without seeing your output

The point answer :

Use -s ( protect args ) and enclose your path in quotes :

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

Works with both spaces or dashes.