Пытаемся безопасно восстановить файлы с сильно зараженных машин Windows XP и 2003, которые пришли к нам в результате приобретения. У меня аналогичная потребность в автоматизации сценария, который будет запускаться на машинах DRBL с загрузкой PXE для 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 не жалуется на это правило фильтрации, но фактически не отфильтровывает «Данные приложения /».
У вас две проблемы:
Во-первых, не используйте кавычки в --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/
исключил это.
Я заставил его работать следующим образом:
Я изменился:
EXCLUDE=( '- "Default User/"' '- "Application Data/"' )
к
EXCLUDE=( '-_Default User/' '-_Application Data/' )
Это удалило двойные кавычки и использовало альтернативный синтаксис подчеркивания «_» после «-». Предыдущий ответ предполагал это, но мне пришлось добавить синтаксис «_», чтобы он работал на меня.
Также изменилось:
FILTER=( "${FILTER[@]}" "--filter='${X}' " );
к
FILTER=( "${FILTER[@]}" "--filter=${X}" );
Это удалило апострофы вокруг замены переменной X.
И изменилось:
"${FILTER[*]}"
к
"${FILTER[@]}"
Это приводит к тому, что каждый элемент массива обрабатывается как отдельный параметр, а не как весь массив, как отмечалось ранее.