Исключение двойных кавычек в динамической команде rsync

Я понимаю, что вам действительно нужно перечислить 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
1
19.06.2018, 15:30
3 ответа

Экранированные двойные кавычки обрабатываются как буквенные символы имени файла. Поскольку вы используете bash, вы можете использовать его массивы для обработки этого.

linkDest=()
[[ -n "$LAST_SNAPSHOT" ]] && linkDest+=('--link-dest' "$BACKUP_ROOT/$LAST_SNAPSHOT")
...

rsync $OPTS $EXCLUDES "${linkDest[@]}" "$MASTER/" "$NEW_SNAPSHOT"

Цитата "${linkDest[@]}"полностью исчезает, если она пуста. В противном случае он раскрывается в список своих значений в кавычках. Если $OPTSи $EXCLUDESтакже являются списками, я бы использовал для них тот же механизм.

2
27.01.2020, 23:43

Проблема в том, что вы сделали двойные кавычки частью имени файла.

Используйте массив для хранения параметров до 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"
2
27.01.2020, 23:43

Разница в том, что экранирование кавычки \"превращает ее в строковый символ.

Так что ошибка, вероятно, правильная:

"/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

-1
27.01.2020, 23:43

Теги

Похожие вопросы