rsync不会删除string数组中的单引号 – 筛选器列表

试图安全地从受到严重感染的Windows XP和2003机器中检索文件,这些机器是通过收购获得的。 我也有类似的需求来自动运行在PXE启动的DRBL机器上运行的rsync到我们的服务器的脚本。

下面的代码会导致用单引号将整个'–filter ='''参数包装到rsync中。 注意回声消除单引号,但不是rsync。 我究竟做错了什么? 将使每个参数在数组中的条目帮助?

失败,因为包装单引号

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

当我运行相同的确切命令,但手动删除包装单引号,rsync运行良好。
作品

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

尝试了没有和没有保护参数。

 #!/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 

工作…没有它不是:

 FILTER+=( --filter=""${X}"" ); RESULTS IN: '--filter=- "Default User/" --filter=- "Application Data/"' 

rsync不会抱怨这个过滤规则,但实际上并没有过滤出“Application Data /”。

我是这样做的:

我变了:

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

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

这删除了双引号,并在“ – ”之后使用了替代的下划线“_”语法。 先前的答案提出了这一点,但我不得不添加“_”语法来为我工作。

也改变了:

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

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

这从Xvariablesreplace周围删除了撇号。

并改变了:

 "${FILTER[*]}" 

 "${FILTER[@]}" 

这会导致数组中的每个元素都被视为单个参数,而不是像前面提到的那样处理整个数组。

你有两个问题:

首先,不要在--filter使用引号(特别是使用--protect-args来表示使用这个来避免不必要的空格),尽pipe我在这里的testing显示了双引号也没有它。 filter应该是- Application Data/ 。 正如你用引号写的那样,它正在寻找名为"Application Data "的文件夹中的文件

另一个问题是你希望每个filter都是rsync的独立参数,所以在命令中使用@而不是*

 rsync --dry-run -vv --stats \ --recursive \ "$PROTECTARGS" \ "${FILTER[@]}" \ '/hddOld/Documents and Settings' \ '/hddNew/' 

经testing:

GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)
rsync version 3.0.7 protocol version 30

我用arr=(ab "cd")创build了一个数组,然后使用touch "${arr[@]}"创build文件

 a b cd 

dir1

 rsync -r --filter='- cd' dir1/ dir2 

ab复制到dir2

 rsync -r --filter='- "cd"' dir1/ dir3 

复制所有的文件,因为rsync正在寻找文件名为"cd"的文件。 还使用mkdir- cd/- "cd/"进行了testing,以确保目录filter的工作方式不同, "cd/"cd/ did排除目录时不排除该目录。