Сгенерированная рыбой команда Rsync имеет неожиданные эффекты
Я использую рыбную оболочку, и у меня есть вспомогательная функция для генерации команды rsync с полностью установленными параметрами. Последняя команда rsync должна быть такой (команда в одной строке, я сделал ее многострочной, потому что ее легче читать):
rsync -razs -e="ssh -p2222" --update --progress \
--exclude=".*" --exclude="__pycache__"
--delete --dry-run \
$source_dir $dest_dir
С терминала все работает нормально, но когда я пытаюсь использовать свою вспомогательную функцию, параметры "исключить", похоже, не действуют. Сгенерированная команда выглядит точно так же, за исключением того, что команда ssh не заключена в кавычки. Тем не менее, это не кажется проблемой, так как я могу подключиться к серверу. Как я уже сказал, единственная проблема заключается в том, что исключения исключаются.
Сгенерированная команда выглядит так:
rsync -razs -e=ssh -p2222 --update --progress \
--exclude=".*" --exclude="__pycache__" \
--delete --dry-run \
/home/some_folder user@host:/home/
Любая идея?
Функция выглядит так:
function ssync -d "rsync through ssh tunnel"
set origin $argv[1]
set destination $argv[2]
set exclude ".*" "__pycache__"
set ssh_config "ssh -p2222"
set params -razs -e="$ssh_config" --update --progress --exclude=\"$exclude\"
if test (count $argv) -gt 2
set option $argv[3]
set params $params --delete
if [ $option = "--delete" ]
set_color red; echo "Warning: Unsafe run!";
read -l -P "Confirm? [y/N] " yesno;
switch $yesno
case '' N n
echo "Sync canceled by user"
return 0
case Y y
echo "Proceeding..."
end
else
set params $params --dry-run
end
end
echo "rsync $params $origin $destination"
rsync $params $origin $destination;
end
[РЕДАКТИРОВАТЬ]: Благодаря ответу Гленна, я понимаю, что использование литералов кавычек в функции является причиной проблемы. Тем не менее, он имеет очень удобный эффект разделения аргумента с несколькими значениями, разделенными пробелами, как arg1 arg2
в нечто вроде --exclude="arg1" --exclude="arg2"
, Есть ли способ получить преимущества без неудобств?
1 ответ
Вы добавляете буквенные кавычки
... --exclude=\"$exclude\"
Это заставит rsync искать файлы, которые буквально содержат кавычки в имени файла.
Вы просто хотите использовать кавычки, чтобы окружить слово
... "--exclude=$exclude"
Помните, что целью кавычек является указание оболочке токенизировать команду так, как вы этого хотите. Фактические кавычки удаляются до того, как оболочка фактически выполнит команду.
ОК, у вас есть список элементов в $ exclude. Вместо этого используйте фигурные скобки: demo:
$ set exclude ".*" file1 file2
$ set params --some stuff --other stuff --exclude={$exclude}
$ echo $params
--some stuff --other stuff --exclude=.* --exclude=file1 --exclude=file2
Обратите внимание, что если $ exclude пусто, параметры не будут содержать опций --exclude:
$ set -e exclude
$ set params --some stuff --other stuff --exclude={$exclude}
$ echo $params
--some stuff --other stuff