How to escape spaces in rsync source and destination paths

Matt McCutchen matt at mattmccutchen.net
Fri Aug 22 01:32:38 GMT 2008


On Thu, 2008-08-21 at 16:32 -0400, Carney Mimms wrote:
> Thank you for taking an interest in my problem of escaping spaces.
> Here is the entire script and the entire output. I am at my wits end
> as I have tried every every trick I know or have heard of, including \
> \\ and adding single quotes. I added —protect-args at your suggestion,
> but it doesn’t seem to change anything. I am running the script as
> root for now to take sudo out of the picture. I have also tried
> putting the paths directly in the command as arguments, rather than as
> script variables.

> #!/bin/bash
> 
> # Space-separated list of directories to back up; edit as needed;
> SOURCE
> #DIRS="/Volumes/Christine/Complete\ Rug\ Image\ Archive/Misc"
> DIRS="admin at 192.168.100.47:/Volumes/Christine/Complete\ Rug\ Image\
> Archive/Layered\ Rooms/"
> # Options to pass to rsync; edit as needed
> # "--update" = update only (don't overwrite newer versions of files)
> # "--delete"= delete files that exist on DESTINATION BUT NOT SOURCE" 
> OPTS="-avAX --progress --delete --rsync-path=/usr/local/bin/rsync
> --protect-args --dry-run" 
> 
> # If you wish to back up to a server via ssh, change the line to
> something like
> #
> BACKUPDIR="remoteusername at someserver.something:/path/to/backup/destination"
> #BACKUPDIR="admin at 192.168.110.46:/Volumes/Paris/Complete Rug Image
> Archive/Misc/"
> BACKUPDIR="/Volumes/Paris/Complete\  Rug\ Image\ Archive/Layered\
> Rooms/"
> # ignore Mac droppings
> EXCLUDES="--exclude .DS_Store --exclude .Trash --exclude Cache
> --exclude Caches"
> 
> # Build the actual command
> # NOTE the specific path to the "special" version of rsync
> COMMAND="/usr/local/bin/rsync  $OPTS $EXCLUDES $DIRS $BACKUPDIR"
> 
> # Informative output
> echo About to run:
> echo $COMMAND
> echo Please do not close this window until it is finished.
> 
> # DO IT!
> $COMMAND
> 
> echo Done.
> 
> # the end.

Here's your problem: when you expand a variable outside of quotes (in
this case $COMMAND), bash word-splits on whitespace in $COMMAND but does
not recognize any form of quoting or escaping within $COMMAND.  Thus,
there is nothing you can put in $COMMAND that will generate an argument
containing a space.  This came up before:

http://lists.samba.org/archive/rsync/2008-April/020620.html

In this situation, I recommend using bash arrays, which let you store,
manipulate, and finally execute lists of arguments without the local
shell mangling spaces in the arguments.  Since you're using
--protect-args, rsync won't let the remote shell mangle the spaces
either, so all you have to do is quote the spaces when they are
originally inserted into an array.  Here's your script rewritten to use
arrays (lightly tested):

-----
#!/bin/bash

# Space-separated list of directories to back up; edit as needed; SOURCE
#DIRS=("admin at 192.168.100.47:/Volumes/Christine/Complete Rug Image Archive/Misc" "admin at 192.168.100.47:/Volumes/Christine/Other Source")
DIRS=("admin at 192.168.100.47:/Volumes/Christine/Complete Rug Image Archive/Layered Rooms/")
# Options to pass to rsync; edit as needed
# "--update" = update only (don't overwrite newer versions of files)
# "--delete"= delete files that exist on DESTINATION BUT NOT SOURCE" 
OPTS=(-avAX --progress --delete --rsync-path=/usr/local/bin/rsync --protect-args --dry-run)

# If you wish to back up to a server via ssh, change the line to something like
# BACKUPDIR="remoteusername at someserver.something:/path/to/backup/destination"
#BACKUPDIR="admin at 192.168.110.46:/Volumes/Paris/Complete Rug Image Archive/Misc/"
BACKUPDIR="/Volumes/Paris/Complete Rug Image Archive/Layered Rooms/"
# ignore Mac droppings
EXCLUDES=(--exclude .DS_Store --exclude .Trash --exclude Cache --exclude Caches)

# Build the actual command
# NOTE the specific path to the "special" version of rsync
COMMAND=(/usr/local/bin/rsync "${OPTS[@]}" "${EXCLUDES[@]}" "${DIRS[@]}" "$BACKUPDIR")

# Informative output
echo About to run:
echo "${COMMAND[*]}"
echo Please do not close this window until it is finished.

# DO IT!
: "${COMMAND[@]}"

echo Done.

# the end.
-----

Matt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part
Url : http://lists.samba.org/archive/rsync/attachments/20080821/c208449c/attachment.bin


More information about the rsync mailing list