Вопрос или проблема
Я переписываю простой скрипт, CopyScript.sh
, который я написал несколько лет назад, чтобы копировать содержимое с моего NAS на USB-диск.
#!/bin/bash
SYNCPATH="/volume1/"
SYNCPATHTO="/volumeUSB1/usbshare/synology-may-2015-bak/"
NAMELOG="/volume1/homes/sando/logrsync.log"
echo "${NAMELOG}"
date >"${NAMELOG}"
rsync --verbose --recursive --size-only --exclude-from 'exclude-list.txt' $SYNCPATH $SYNCPATHTO >> $NAMELOG 2>&1
date >> "${NAMELOG}"
echo DONE >> "${NAMELOG}"
Однако, когда я выполняю bash CopyScript.sh
, я получаю следующую ошибку: “неоднозначный редирект: строка 7: 1”
И действительно, когда я смотрю на файлы в своей файловой системе, я вижу 2 журнала с именем logrsync.log: один объемом 1 кБ и один объемом 0 кБ. Я понимаю, что это дает неоднозначный редирект, но почему два файла? Я верю, что очень похожий код работал в моей старой системе. Что я упускаю?
С уважением, Сандо
Попробуйте поместить переменную NAMELOG в кавычки в редиректе rsync, то есть “${NAMELOG}”
Вы пытаетесь записать активность rsync в лог-файл
Но это не следует делать так с помощью редиректа >>, а через некоторые параметры
--log-file=FILE override the "log file" setting
--log-file-format=FMT override the "log format" setting
**--log-file=FIL**E Этот параметр заставляет rsync записывать то, что он делает, в файл. Это похоже на ведение журнала, которое делает демон, но может быть запрошено для клиентской и/или серверной стороны недемоничной передачи. Если это указано как клиентская опция, ведение журнала передачи будет включено с форматом по умолчанию "%i %n%L". Смотрите параметр
**--log-file-format**, если вы хотите переопределить это.
**--log-file-format=FORMAT** Это позволяет вам точно указать, какие данные для каждого обновления записываются в файл, указанный в параметре --log-file (который также должен быть указан, чтобы этот параметр имел какое-либо действие). Если вы укажете пустую строку, обновленные файлы не будут упомянуты в лог-файле. Для списка возможных символов экранирования смотрите настройку "log format" в manpage rsyncd.conf. Формат по умолчанию, используемый, если --log-file указан, и этот параметр не используется, это ’%i %n%L’.
Поэтому я бы попробовал следующее:
rsync --verbose --recursive --size-only --exclude-from 'exclude-list.txt' --log-file=$NAMELOG $SYNCPATH $SYNCPATHTO
Ответ или решение
Ошибка "ambiguous redirect" в вашем скрипте Bash связана с неправильной обработкой переменных в команде перенаправления вывода. Давайте разберём вашу ситуацию и предложим решение.
Проблема
Когда вы запускаете скрипт CopyScript.sh
, система выдаёт ошибку "ambiguous redirect: line 7: 1". Это указывает на проблему в строке, где вы выполняете перенаправление вывода командной строки. В вашем случае, это строка с командой rsync
, где результаты её выполнения перенаправляются в файл через переменную NAMELOG
.
Пояснение
Ошибка "противоречивое (ambiguous) перенаправление" обычно возникает, когда имена файлов, используемые в операциях, запутаны из-за наличия пробелов или других специальных символов, особенно если они не заключены в кавычки. Предоставленные вами переменные, такие как SYNCPATH
, SYNCPATHTO
и NAMELOG
, могут содержать такие символы, что приведёт к неверной интерпретации пути файлов.
Почему создаются два файла
Действительно, появление двух файлов указывает на то, что путь к файлу логов разделённым из-за пробелов был воспринят как два отдельных аргумента, что объясняет наличие файла размером 0 кБ. Вторая часть имени могла быть ошибочно воспринята как дополнительный файл, что и создаёт "амбигуацию".
Решение
-
Заключение переменных в кавычки: Важно всегда заключать переменные, содержащие пути, в двойные кавычки чтобы избежать проблем с интерпретацией. Попробуйте отредактировать строки следующим образом:
echo "${NAMELOG}" date > "${NAMELOG}" rsync --verbose --recursive --size-only --exclude-from 'exclude-list.txt' "$SYNCPATH" "$SYNCPATHTO" >> "${NAMELOG}" 2>&1 date >> "${NAMELOG}" echo DONE >> "${NAMELOG}"
-
Использование встроенных функций rsync для логирования: Вместо стандартного перенаправления вы можете использовать специальную опцию
--log-file=
в команде rsync, которая создаёт лог-файл без дополнительных усилий с вашей стороны:rsync --verbose --recursive --size-only --exclude-from 'exclude-list.txt' --log-file="${NAMELOG}" "$SYNCPATH" "$SYNCPATHTO"
Заключение
Применяя вышеуказанные коррективы, вы сможете устранить ошибку "ambiguous redirect" и корректно вести логирование операций rsync в системе. Всегда учитывайте важность правильного использования кавычек с переменными в Bash, чтобы избежать нежелательных ошибок. Надежность и читаемость кода улучшается от использования встроенных возможностей rsync для логирования.