我正在使用 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