Команда Rsync, созданная Fish, имеет неожиданные эффекты

Команда Rsync, созданная Fish, имеет неожиданные эффекты

Я использую 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

Связанный контент