0

I'm trying to build a bash script around bazaarvcb utility but I'm having some problems when constructing the parameters. Basically, this is the command I want to be executed (simplified version):

bazaarvcb backup -H 192.168.1.100 -u user -p password --roll-out 4 \
--exclude-disk "[Datastore1] MyVM - NAS/MyVM-NAS_1.vmdk" \
--exclude-disk "[Datastore2] MyVM - NAS/MyVM-NAS_2.vmdk" \
"MyVM - NAS" "/home/user/backup/MyVM - NAS/"

Executing the above on command line or pasting it in a simple bash script, everything works great. But when I try to replace the exclude disks (or even the VM name) as variables parameters inside the script, I get problems.

Example:

#!/usr/bin/env bash

set -o xtrace

readonly __VM="MyVM - NAS"
readonly __BACKUPROOT="/home/user/backup/MyVM - NAS/"

readonly -a __EXCLUDE_DISKS=( \
'[Datastore1] MyVM - NAS/MyVM-NAS_1.vmdk' \
'[Datastore2] MyVM - NAS/MyVM-NAS_2.vmdk' )

disks_excluded=""
for (( i = 0 ; i < ${#__EXCLUDE_DISKS[@]} ; i++ )); do
    disks_excluded+="--exclude-disk \"${__EXCLUDE_DISKS[$i]}\" "
done

bazaarvcb backup -H 192.168.1.100 -u user -p password --roll-out 4 ${disks_excluded} "${__VM}" "${__BACKUPROOT}"

The result when executing the above script is:

+ readonly '__VM=MyVM - NAS'
+ __VM='MyVM - NAS'
+ readonly '__BACKUPROOT=/home/user/backup/MyVM - NAS/'
+ __BACKUPROOT='/home/user/backup/MyVM - NAS/'
+ __EXCLUDE_DISKS=('[Datastore1] MyVM - NAS/MyVM-NAS_1.vmdk' '[Datastore2] MyVM - NAS/MyVM-NAS_2.vmdk')
+ readonly -a __EXCLUDE_DISKS
+ disks_excluded=
+ (( i = 0  ))
+ (( i < 2  ))
+ disks_excluded+='--exclude-disk "[Datastore1] MyVM - NAS/MyVM-NAS_1.vmdk" '
+ (( i++  ))
+ (( i < 2  ))
+ disks_excluded+='--exclude-disk "[Datastore2] MyVM - NAS/MyVM-NAS_2.vmdk" '
+ (( i++  ))
+ (( i < 2  ))
+ bazaarvcb backup -H 192.168.1.100 -u user -p password --roll-out 4 --exclude-disk '"[Datastore1]' MyVM - 'NAS/MyVM-NAS_1.vmdk"' --exclude-disk '"[Datastore2]' MyVM - 'NAS/MyVM-NAS_2.vmdk"' 'MyVM - NAS' '/home/user/backup/MyVM - NAS/'
usage: bazaarvcb [-h] [--version]  ...
bazaarvcb: error: unrecognized arguments: NAS/MyVM-NAS_1.vmdk" MyVM - NAS/MyVM-NAS_2.vmdk" MyVM - NAS /home/user/backup/MyVM - NAS/

Any help would be appreciated.

1 Answers1

1

The shell parses quotes before expanding variable references, so putting quotes in a variable's value doesn't do anything useful -- by the time they're expanded into the command, it's too late for them to have the intended effect. Thus, when you use:

...
disks_excluded+="--exclude-disk \"${__EXCLUDE_DISKS[$i]}\" "
...
bazaarvcb ... ${disks_excluded} ...

bazaarvcb gets passed arguments like '--exclude-disk', '"[Datastore1]", 'MyVM', '-', and 'NAS/MyVM-NAS_1.vmdk"'. The double-quotes are treated as part of the arguments, rather than quotes around arguments! Fortunately, the solution is simple: store disks_excluded as an array, just as you did with __EXCLUDE_DISKS. Note that you can also simplify the for loop by iterating over the array elements, rather than indexes:

...
disks_excluded=() # Note that this declares disks_excluded as an empty array
for disk in "${__EXCLUDE_DISKS[@]}"; do
    disks_excluded+=("--exclude-disk" "${disk}")
done

bazaarvcb backup -H 192.168.1.100 -u user -p password --roll-out 4 "${disks_excluded[@]}" "${__VM}" "${__BACKUPROOT}"

Note that the double-quotes around ${__EXCLUDE_DISKS[@]} and ${disks_excluded[@]} are required (as are the [@]s).

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151