Я понимаю, что вам действительно нужно перечислить N дней, а не жестко запрограммированные пять, которые вы указали в своем вопросе. Вот решение bash
, которое отвечает этому требованию:
n=5
today=$(date +'%Y-%m-%d')
for ((d=1; n>0; d++))
do
# Adjust this next line to get the date format you require, e.g. +'%Y%m%d'
date=$(date --date "$today -$d day")
nday=$(date --date "$today -$d day" +'%w')
if [[ $nday > 0 && $nday < 6 ]]
then
# Adjust this next line to output whatever you really need
echo "n=$n, d=$d, nday=$nday, date=$date: WEEKDAY"
: $((n--))
fi
done
Вывод для n = 5
, запуск 5 ноября 2015 г.
n=5, d=1, nday=3, date=Wed, 4 Nov 2015 00:00:00: WEEKDAY
n=4, d=2, nday=2, date=Tue, 3 Nov 2015 00:00:00: WEEKDAY
n=3, d=3, nday=1, date=Mon, 2 Nov 2015 00:00:00: WEEKDAY
n=2, d=6, nday=5, date=Fri, 30 Oct 2015 00:00:00: WEEKDAY
n=1, d=7, nday=4, date=Thu, 29 Oct 2015 00:00:00: WEEKDAY
Экранированные двойные кавычки обрабатываются как буквенные символы имени файла. Поскольку вы используете bash
, вы можете использовать его массивы для обработки этого.
linkDest=()
[[ -n "$LAST_SNAPSHOT" ]] && linkDest+=('--link-dest' "$BACKUP_ROOT/$LAST_SNAPSHOT")
...
rsync $OPTS $EXCLUDES "${linkDest[@]}" "$MASTER/" "$NEW_SNAPSHOT"
Цитата "${linkDest[@]}"
полностью исчезает, если она пуста. В противном случае он раскрывается в список своих значений в кавычках. Если $OPTS
и $EXCLUDES
также являются списками, я бы использовал для них тот же механизм.
Проблема в том, что вы сделали двойные кавычки частью имени файла.
Используйте массив для хранения параметров до rsync
.
В оболочке /bin/sh
(также будет работать вbash
):
# options that are always set
set -- --archive --verbose
# add --link-dest=DIR if needed
if [ -n "$LAST_SNAPSHOT" ]; then
set -- "$@" --link-dest="$BACKUP_ROOT/$LAST_SNAPSHOT"
fi
# add some --excludes
set -- "$@" --exclude='*.ext' --exclude='dir/***'
# call rsync
rsync "$@" "$MASTER/" "$NEW_SNAPSHOT"
Это использует единственный массив, доступный в оболочке POSIX (, если не расширен, как bash
и другие ), массив позиционных параметров. Установив записи в этом массиве (с помощьюset
)и добавив к нему по мере необходимости, мы можем быть уверены, что аргументы в кавычках дляrsync
(или любой команды )обрабатываются надлежащим образом. Затем в вызове rsync
мы используем "$@"
, что гарантирует, что записи в массиве будут индивидуально заключены в двойные кавычки и, следовательно, защищены от разделения слов и создания имени файла оболочкой.
То же самое, но с bash
массивом:
# options that are always set
opts=( --archive --verbose )
# add --link-dest=DIR if needed
if [ -n "$LAST_SNAPSHOT" ]; then
opts+=( --link-dest="$BACKUP_ROOT/$LAST_SNAPSHOT" )
fi
# add some --excludes
opts+=( --exclude='*.ext' --exclude='dir/***' )
# call rsync
rsync "${opts[@]}" "$MASTER/" "$NEW_SNAPSHOT"
Разница в том, что экранирование кавычки \"
превращает ее в строковый символ.
Так что ошибка, вероятно, правильная:
"/home/backuptest/dest/backuptest/20180619_134044"
Если кавычки являются частью имени, это отличается от
/home/backuptest/dest/backuptest/20180619_134044
Чего ты хочешь Рекомендуемый способ решить эту проблему — использовать переменные ${}. например :
$ myvar=var
$ echo "\"$myvar\""
"var"
$ echo "${myvar}"
var
Что-то вроде " --ссылка -место назначения "${РЕЗЕРВНАЯ КОПИЯ _КОРЕНЬ}"/"${ПОСЛЕДНИЙ _СНИМОК}"" Должен приблизить вас.
Подробнее об этом :https://stackoverflow.com/questions/8748831/when-do-we-need-curly-braces-around-shell-variablesа такжеhttp://wiki.bash-hackers.org/syntax/pe#simple_usage