Rsync игнорирует двойные кавычки в скрипте

Rsync игнорирует двойные кавычки в скрипте

Когда переменная "$exclude_list"вызывается как параметр, rsync игнорирует двойные кавычки и каким-то образом включает домашнюю папку, даже если она не упомянута в скрипте. Я пытаюсь обернуть ее в "${exclude_list}", но это тоже не помогло.

Отображение содержимого переменной перед ее использованием в сочетании с rsyncпоказывает, что она корректна.

Еще одна странность заключается в том, что когда я это делаю, echo rsync ...вывод оказывается правильным и никаких ошибок нет.

Часть проблемного bash-скрипта:

    echo "$exclude_list"
    rsync -av --dry-run "$exclude_list" "$src" "$dest" >> /var/log/rsync.log || {
      sendmail "Error: rsync failed for folder $src."; exit 1; }

Выход:

   --exclude=lost+found
   rsync: [sender] link_stat "/home/user/ --exclude=lost+found" failed: No such file or 
   directory (2)
   rsync error: some files/attrs were not transferred (see previous errors) (code 23) at 
   main.c(1333) [sender=3.2.3]

Вот MCVE:

#!/bin/bash

# List of source folders
SRC_FOLDERS=(
  [0]="/mnt/load-1/"
  [1]="/mnt/load-2/"
)

# List of backup folders
DEST_FOLDERS=(
  [0]="/mnt/load-1-b/"
  [1]="/mnt/load-2-b/"
)

# List of folders to exclude during backup
EXCLUDE_FOLDERS=(
  "lost+found"
  "lost-found"
)

  # Form the exclude list for rsync
  for exclude_folder in "${EXCLUDE_FOLDERS[@]}"; do
    exclude_list="$exclude_list --exclude=$exclude_folder"
  done

# Loop through each folder pair
for i in "${!SRC_FOLDERS[@]}"; do
  src=${SRC_FOLDERS[$i]}
  dest=${DEST_FOLDERS[$i]}

    rsync -av --dry-run "$exclude_list" "$src" "$dest"

done

решение1

Проблема в том,

for exclude_folder in "${EXCLUDE_FOLDERS[@]}"; do
  exclude_list="$exclude_list --exclude=$exclude_folder"
done

Вы перебираете массив EXCLUDE_FOLDERSи создаете из него переменную, не являющуюся массивом exclude_list. Когда она позже упоминается как "$exclude_list", оболочка расширяет ее до одного слова.

До того, как forцикл exclude_listбудет пустым. Первое назначение внутри цикла заставляет переменную начинаться с --exclude…. Обратите внимание на начальный пробел. Из-за этого пробела rsyncне распознает это слово как опцию; он распознает его какотносительный путь. Я думаю, что ваш текущий рабочий каталог — /home/user/. Абсолютный путь — /home/user/ --exclude=…, поэтому такой файл не существует, об этом и говорится в ошибке.

Даже если бы начального пробела не было и exclude_listон был создан каким-то образом как --exclude=… --exclude=…, это все равно было бы неправильно. "$exclude_list"всегда расширяется до одного слова. Вы хотите, --exclude=…чтобы каждый был отдельным аргументом для rsync.

Не цитирование $exclude_listможет сработать, но это плохое решение; напримерон завершится (или может завершиться) ошибкой, если элементы содержат EXCLUDE_FOLDERSпробелы, табуляции или новые строки (или подстановочные знаки, которые вызывают подстановку).

Пожалуйста прочтиКак можно выполнить команду, хранящуюся в переменной?В Bash часто лучше использовать массив. Создайте exclude_listмассив:

for exclude_folder in "${EXCLUDE_FOLDERS[@]}"; do
  exclude_list+=("--exclude=$exclude_folder")
done

Затем при вызове rsyncиспользуйте "${exclude_list[@]}".

Связанный контент