Fixing rsync Not Removing Single Quotes Around Array of Strings

bashrsync

Trying to safely retrieve files from heavily infected Windows XP and 2003 machines that came to us from an acquisition. I have a similar need for automating a script that would run on PXE booted DRBL machines to rsync to our server.

The following code results in single quotes wrapping the entire '–filter=''' parameter to rsync. Note echo strips the single quotes, but not rsync. What am i doing wrong? Would making every parameter an entry in an array help?

FAILS because wrapping single quotes:

'--filter='\''- "Default User/"'\''  --filter='\''- "Application Data/"'\'' '

When i run the same exact command but manually remove the wrapping single quotes, rsync runs fine.
WORKS:

--filter='\''- "Default User/"'\''  --filter='\''- "Application Data/"'\'' 

Have tried without and without –protect-args.


#!/bin/sh -x

PROTECTARGS=--protect-args
EXCLUDE=( '- "Default User/"' '- "Application Data/"' )
echo EXCLUDE="${EXCLUDE[*]}" 
FILTER=()
for X in "${EXCLUDE[@]}"; do
  FILTER=( "${FILTER[@]}" "--filter='${X}' " );
done;
echo FILTER="${FILTER[*]}"

if [ "1" == "1" ]; then
rsync --dry-run -vv --stats \
      --recursive \
      "$PROTECTARGS"  \
      "${FILTER[*]}"  \
      '/hddOld/Documents and Settings' \
      '/hddNew/'
fi;

OUTPUT:


FILTER=--filter='- "Default User/"'  --filter='- "Application Data/"' 
+ '[' 1 == 1 ']'
+ rsync --dry-run -vv --stats --recursive --protect-args '--filter='\''- "Default User/"'\''  --filter='\''- "Application Data/"'\'' ' '/hddOld/Documents and Settings' /hddNew/
Unknown filter rule: `'- "Default User/"'  --filter='- "Application Data/"' '
rsync error: syntax or usage error (code 1) at exclude.c(817) [client=3.0.6]


bash-4.1.2-14.el6.x86_64
rsync  version 3.0.6  protocol version 30
rsync-3.0.6-9.el6.x86_64
CentOS 6.4 x64

WORKS … NO IT DOES NOT:


FILTER+=( --filter=""${X}""  );

RESULTS IN:
'--filter=- "Default User/" --filter=- "Application Data/"'  

rsync does not complain about this filter rule but does not actually filter out "Application Data/".

Best Answer

I got it to work by doing this:

I changed:

EXCLUDE=( '- "Default User/"' '- "Application Data/"' )

to

EXCLUDE=( '-_Default User/' '-_Application Data/' )

This removed the double quotes and used the alternate underscore "_" syntax after the "-". A prior answer suggested this but I had to add the "_" syntax to get it to work for me.

Also changed:

FILTER=( "${FILTER[@]}" "--filter='${X}' " );

to

FILTER=( "${FILTER[@]}" "--filter=${X}" );

This removed the apostrophes from around the X variable substitution.

And changed:

"${FILTER[*]}"

to

"${FILTER[@]}"

This causes each element of the array to be treated as a single parameter, rather than the whole array as noted previously.

Related Topic