尝试安全地从我们收购的受严重感染的 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
,并b
致dir2
。
rsync -r --filter='- "c d"' dir1/ dir3
复制所有文件,因为 rsync 正在寻找"c d"
文件名中带有引号的文件。还使用mkdir
和- c d/
和进行了测试- "c d/"
,以确保目录过滤器的工作方式没有不同,并且"c d/"
没有排除目录而c d/
排除了它。