O comando Rsync gerado por peixe tem efeitos inesperados

O comando Rsync gerado por peixe tem efeitos inesperados

Estou usando o fish shell e tenho uma função auxiliar para gerar um comando rsync com meus parâmetros todos definidos. O comando rsync final deve ser assim (o comando está em uma linha, fiz multilinha porque é mais fácil de ler):

rsync -razs -e="ssh -p2222" --update --progress \ 
    --exclude=".*" --exclude="__pycache__" 
    --delete --dry-run \
    $source_dir $dest_dir

No terminal funciona bem, mas quando tento usar minha função auxiliar, os parâmetros "excluir" parecem não ter efeito. O comando gerado parece exatamente o mesmo, exceto que o comando ssh não está entre aspas. No entanto, isso não parece ser um problema, pois consigo me conectar ao servidor. Como eu disse, o único problema é que as exclusões são ignoradas.

O comando gerado fica assim:

rsync -razs -e=ssh -p2222 --update --progress \
    --exclude=".*" --exclude="__pycache__" \
    --delete --dry-run \
    /home/some_folder user@host:/home/

Qualquer ideia?

A função fica assim:

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

[EDITAR]: Graças à resposta de Glenn, entendo que o uso de literais de aspas na função é o que causa o problema. No entanto, tem o efeito muito conveniente de separar um argumento com vários valores separados por espaços arg1 arg2em algo como --exclude="arg1" --exclude="arg2". Tem como ter as vantagens sem os inconvenientes?

Responder1

Você está adicionando caracteres de aspas literais

... --exclude=\"$exclude\"

Isso fará com que o rsync procure arquivos que literalmente tenham aspas no nome do arquivo.

Você só quer usar aspas para cercar a palavra

... "--exclude=$exclude"

Lembre-se de que o objetivo das aspas é instruir o shell a tokenizar o comando da maneiravocêquero que isso aconteça. Os caracteres de aspas reais são removidos antes que o shell execute o comando.


OK, você tem umlistade itens em $exclude. Em vez disso, use colchetes: demonstração:

$ set exclude ".*" file1 file2
$ set params --some stuff --other stuff --exclude={$exclude}
$ echo $params
--some stuff --other stuff --exclude=.* --exclude=file1 --exclude=file2

Observe que se $exclude estiver vazio, os parâmetros conterãonão--excluir opções:

$ set -e exclude
$ set params --some stuff --other stuff --exclude={$exclude}
$ echo $params
--some stuff --other stuff

informação relacionada