Сгенерированная рыбой команда 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
Другие вопросы по тегам