Я использую fish shell и у меня есть вспомогательная функция для генерации команды rsync с моими параметрами. Окончательная команда rsync должна быть такой (команда в одну строку, я сделал ее многострочной, потому что ее легче читать):
rsync -razs -e="ssh -p2222" --update --progress \
--exclude=".*" --exclude="__pycache__"
--delete --dry-run \
$source_dir $dest_dir
Из терминала все работает нормально, но когда я пытаюсь использовать свою вспомогательную функцию, параметры «exclude», похоже, не оказывают никакого эффекта. Сгенерированная команда выглядит точно так же, за исключением того, что команда 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 пуст, параметры будут содержатьнет--исключить параметры:
$ set -e exclude
$ set params --some stuff --other stuff --exclude={$exclude}
$ echo $params
--some stuff --other stuff