1

Afternoon ServerFault,

I have hit a problem that I can seem to reach a solution to, I currently have a backup script that is meant to rsync VMs off our VMWare box onto our backup server, the problem I have hit is this

**** Starting New Backup
Date: Thu Jan 29 14:09:44 EST 2015
Host: vmhost2
Backup Location: /srv/backups/prod
Dry Run: true

+++=== New VM Backup [27] on [vmhost2] ===+++
---> Target: iDRAC\ Nat
---> VM State: off
rsync -avzhP --delete-after --stats -n root@vmhost2:"/vmfs/volumes/OfficeProd/iDRAC\ Nat" "/srv/backups/prod"
---> RSYNCing VM files
Unexpected local arg: Nat"
If arg is a remote file/dir, prefix it with a colon (:).
rsync error: syntax or usage error (code 1) at main.c(1246) [Receiver=3.0.9]
---! RSYNC Failed, ...
..... truncated .....
+++=== Backup Finished For [27] on [vmhost2] ===+++

An error occurred.  Please check /var/log/backups/prod.log

But if I run the command echoed, it works fine

$ rsync -avzhP --delete-after --stats -n root@vmhost2:"/vmfs/volumes/OfficeProd/iDRAC\ Nat" "/srv/backups/prod" 
receiving file list ... 
16 files to consider
iDRAC Nat/
iDRAC Nat/iDRAC Nat-e4289c3b.vswp
iDRAC Nat/iDRAC Nat-flat.vmdk
....truncated....
sent 71 bytes  received 411 bytes  321.33 bytes/sec
total size is 17.83G  speedup is 36996625.28 (DRY RUN)

Here is how I can trying to run the command in the script

Note: $rsynccmd is set by rsynccmd="rsync -avzhP --delete-after --stats"

if $dryrun
then
  rsynccmd_compiled="$rsynccmd -n root@$vmhost:\"$datastore\" \"$backupprefix\""
  echo $rsynccmd_compiled
else
  rsynccmd_compiled="$rsynccmd root@$vmhost:\"$datastore\" \"$backupprefix\" 2>&1"
fi

log "---> RSYNCing VM files"
cmdresult=`$rsynccmd_compiled`
EXITCODE=$?

if [ $EXITCODE -ne 0 ]
then
  chkcmd $? rsync.backup "$cmdresult"

  log "---! RSYNC Failed, trying again $retrylimit more times"

  EXITCODE=1
  retrycount=0
  until [ $EXITCODE -eq 0 ]; do
    retrycount=$((retrycount + 1))

    if [ $retrycount -gt $retrylimit ]
    then
      break
    fi

    log "---> RSYNC Retry #$retrycount"
    cmdresult=`$rsynccmd_compiled`
    EXITCODE=$?
    chkcmd $EXITCODE rsync.backup.retry "$cmdresult"
    sleep 5
  done
fi

Any help with this is highly appreciated!

Liam
  • 111
  • 5
  • Don't store the rsync command in a variable, it doesn't work. See [BashFAQ #50: I'm trying to put a command in a variable, but the complex cases always fail!](http://mywiki.wooledge.org/BashFAQ/050). Also, `echo` isn't showing you what you think it is... try running `echo rsync -avzhP --delete-after --stats -n root@vmhost2:"/vmfs/volumes/OfficeProd/iDRAC\ Nat" "/srv/backups/prod"` and note that it prints the string AFTER quotes have been removed. – Gordon Davisson Jan 29 '15 at 05:26

1 Answers1

0

The backticks (`) introduce their own additional need for escaping. I find that using bash's $(...) to be better since it doesn't require additional escaping.

Try to replace:

cmdresult=`$rsynccmd_compiled`

With:

cmdresult=$($rsynccmd_compiled)

The alternative would be to replace each single backslash with triple in rsynccmd_compiled:

  rsynccmd_compiled="$rsynccmd root@$vmhost:\\\"$datastore\\\" \\\"$backupprefix\\\" 2>&1"

For the curious, the number of backslashes for a given nesting level is (2^n)-1, meaning 0, 1, 3, 7, 15, ... The $(...) syntax may be nested without any backslash explosion.

Dan Armstrong
  • 821
  • 4
  • 6
  • Neither worked, I even tried them together but every different edit always comes out with the same problem :\ – Liam Jan 29 '15 at 04:14
  • Due to the space in the path, the --protect-args may also need to be used in conjunction: http://unix.stackexchange.com/questions/104618/how-to-rsync-over-ssh-when-directory-names-have-spaces – Dan Armstrong Jan 29 '15 at 04:22
  • Nope not even that worked, what is strange is that I make all these edits and they don't work but if I run the command echoed out as the compiled command they work o_O – Liam Jan 29 '15 at 04:42
  • Here's an idea. Perhaps make some symbolic links that let you bypass that space entirely. At least then you can eliminate one part of the complexity. – Dan Armstrong Jan 30 '15 at 07:05
  • Hello from the future. Pass your variable to a new bash -c: `bash -c "$rsynccmd_compiled"` – Dan Armstrong Feb 14 '23 at 08:26