rsync 不会删除字符串数组周围的单引号--过滤列表

rsync 不会删除字符串数组周围的单引号--过滤列表

尝试安全地从我们收购的受严重感染的 Windows XP 和 2003 机器中检索文件。我也有类似的需求,即自动执行一个脚本,该脚本将在 PXE 启动的 DRBL 机器上运行,以 rsync 到我们的服务器。

以下代码导致单引号将整个 '--filter=''' 参数括在 rsync 中。请注意,echo 会删除单引号,但 rsync 不会。我做错了什么?将每个参数设为数组中的条目有帮助吗?


失败,因为用单引号括起来

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


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

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

已尝试过不使用和不使用--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;

输出:


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/”。

答案1

我通过这样做让它工作:

我变了:

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

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

这样就删除了双引号,并在“-”后使用了替代下划线“_”语法。先前的答案建议这样做,但我必须添加“_”语法才能使其为我工作。

还改变了:

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

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

这删除了 ​​X 变量替换周围的撇号。

并改变:

"${FILTER[*]}"

"${FILTER[@]}"

这会导致数组的每个元素被视为单个参数,而不是前面提到的整个数组。

答案2

你有两个问题:

首先,不要使用引号--filter(尤其是--protect-args表示使用引号来避免转义空格,尽管我在这里的测试表明,双引号在没有引号的情况下也会按字面意思理解)。过滤器应该是- Application Data/。正如您用引号编写的那样,它正在寻找"名为的文件夹中名为的文件"Application Data

另一个问题是您希望每个过滤器作为的单独参数,因此在命令中rsync使用@而不是:*

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

已测试:

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

我使用 创建了一个数组arr=(a b "c d"),然后用来touch "${arr[@]}"创建文件

a
b
c d

dir1

rsync -r --filter='- c d' dir1/ dir2

a,并bdir2

rsync -r --filter='- "c d"' dir1/ dir3

复制所有文件,因为 rsync 正在寻找"c d"文件名中带有引号的文件。还使用mkdir- c d/和进行了测试- "c d/",以确保目录过滤器的工作方式没有不同,并且"c d/"没有排除目录而c d/排除了它。

相关内容