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