
Действительно борюсь с тем, чтобы заставить переменную аргумента команды работать с rsync. Поведение, которое я вижу, это эта ошибка из скрипта:
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(601) [sender=3.0.7]
Однако скрипт выводит команду, которую он собирается запустить, через echo, и точно такая же команда, скопированная в терминал (или вставленная обратно в скрипт в качестве первой строки с выходом после нее), работает просто отлично ?!
Код скрипта, который выполняет rsync (check_flags в этом случае пуст):
rsync_cmd=(${check_flags} -rWltpgoDvdHP --delete-before -- \"${backup_dir}\" \"admin@nas-1:${backup_basename}/\")
echo "CMD to run: rsync ${rsync_cmd[@]}"
rsync ${rsync_cmd[@]}
Выход:
CMD to run: rsync -rWltpgoDvdHP --delete-before -- "/share/CACHEDEV1_DATA/veeam_backup_daily/Daily backup _@1am__1" "admin@nas-1:/share/CACHEDEV1_DATA/veeam_backup_daily/"
Я читал в интернете, что использование массива должно помочь решить эту проблему, но в данном случае этого не произошло. Я почти уверен, что это легко исправить, но это сводит меня с ума!
решение1
Оболочка анализирует кавычки перед заменой переменных, поэтому включение кавычек в значение переменной не делает того, что вы ожидаете (и echo
вводит в заблуждение, поскольку не показывает это различие). Что вам следует сделать, так это использовать неэкранированные кавычки при определении массива (чтобы они анализировались как разделители вокруг элементов массива, а не как часть значения массива), затем заключить ссылку на массив в двойные кавычки (чтобы она не разбивала по словам или не расширяла значения в массиве с помощью подстановочных знаков). Я бы также заменил команду echo
на , printf
которая покажет, что произойдет, более точно:
rsync_cmd=(${check_flags} -rWltpgoDvdHP --delete-before -- "${backup_dir}" "admin@nas-1:${backup_basename}/")
printf "%q " CMD to run: rsync "${rsync_cmd[@]}"
printf "\n"
rsync "${rsync_cmd[@]}"
Обратите внимание, что printf
может не отобразиться то, что вы ожидаете — он напечатаетэквивалентпредставление команды, которая будет выполнена, но существует множество различных эквивалентных представлений каждого аргумента, и он выберет одно на основе своих предпочтений, а не того, как оно было изначально введено. Кстати, вы также можете использовать set -x
для отладки таких вещей, но (как и в случае с printf "%q "
) он может использовать представление, отличное от ожидаемого.