Fish生成的Rsync命令有意想不到的效果

Fish生成的Rsync命令有意想不到的效果

我正在使用 fish shell,并且我有一个辅助函数来生成一个 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

[编辑]:感谢 Glenn 的回答,我明白了函数中使用引号文字是导致问题的原因。但是,它具有非常方便的效果,可以将具有多个值的参数(用空格分隔)分隔成类似arg1 arg2的内容--exclude="arg1" --exclude="arg2"。有没有办法既有优势又没有不便之处?

答案1

您正在添加文字引号字符

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

这将使 rsync 查找文件名中确实带有引号的文件。

你只需要用引号把单词括起来

... "--exclude=$exclude"

请记住,引号的目的是指示 shell 按以下方式标记命令希望如此。实际的引号字符在 shell 实际执行命令之前被删除。


好的,你有一个列表$exclude 中的项目。请改用括号:演示:

$ 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

相关内容