Bash
rsync 從 $@ 傳遞多個排除
我正在嘗試圍繞我的 rsync 命令製作一個包裝器以重用程式碼。我需要傳遞源文件夾、目標文件夾,然後是任意數量的排除目錄。這是我的日誌;基本上我正在從我的“vararg”參數中建構我的多個 rsync 的 –exclude 參數。可能有更好的方法,但我發現一個足夠好了。
function run_backup(){ source="$1" target="/backups/unraid$2" #Copying $source into remote folder $target # Building my exclude params if [ $# -ge 3 ]; then excludes="--exclude '$3'" while shift && [ -n "$3" ]; do echo $excludes excludes="${excludes} --exclude '$3'" done else excludes = "--exclude '/tmp'" # Dummy exclude; I'll handle this case later fi echo $excludes # Creating folder because rsync crash otherwise n some case ssh -p 22 -i /home/backup/.ssh/mykey unraid@94.23.49.55 "mkdir -p $target" # Executing the copy set -e sudo rsync -azvh \ -e "ssh -p 22-i /home/backup/.ssh/mykey "\ --progress \ --delete \ $excludes \ $source \ unraid@69.69.69.69:$target } mkdir -p /tmp/dummy echo "dummy" > /tmp/dummy/save-ignored-1 echo "dummy" > /tmp/dummy/save-ignored-2 echo "dummy" > /tmp/dummy/save-test run_backup /tmp/dummy/ /dummy /tmp/dummy/save-ignored-1 /tmp/dummy/save-ignored-2 /tmp/toto /tmp/tata /tmp/tutu #TODO
--exclude '/tmp/dummy/save-ignored-1' --exclude '/tmp/dummy/save-ignored-1' --exclude '/tmp/dummy/save-ignored-2' --exclude '/tmp/dummy/save-ignored-1' --exclude '/tmp/dummy/save-ignored-2' --exclude '/tmp/toto' --exclude '/tmp/dummy/save-ignored-1' --exclude '/tmp/dummy/save-ignored-2' --exclude '/tmp/toto' --exclude '/tmp/tata' --exclude '/tmp/dummy/save-ignored-1' --exclude '/tmp/dummy/save-ignored-2' --exclude '/tmp/toto' --exclude '/tmp/tata' --exclude '/tmp/tutu' ++ ssh -p 22-i /home/backup/.ssh/mykey unraid@69.69.69.69 'mkdir -p /backups/unraid/dummy' ++ sudo rsync -azvh -e 'ssh -p 22 -i /home/backup/.ssh/mykey' --progress --delete --exclude ''\''/tmp/dummy/save-ignored-1'\''' --exclude ''\''/tmp/dummy/save-ignored-2'\''' --exclude ''\''/tmp/toto'\''' --exclude ''\''/tmp/tata'\''' --exclude ''\''/tmp/tutu'\''' /tmp/dummy/ unraid@94.23.49.55:/backups/unraid/dummy
我們可以看到
$excludes
var 包含我想要的內容;但是當我將它傳遞給 rsync 時,bash 正在對它做一些魔術。我不知道如何避免這種情況。我想這與擴展有關,但我找不到與我的或相關文件類似的問題。編輯:第一次回答後的程式碼:
function run_backup(){ excludes=() if [ $# -ge 3 ]; then echo $3 excludes+=(--exclude $3) while shift && [ -n "$3" ]; do echo $3 excludes+=(--exclude $3) done else excludes+=(--exclude /tmp) fi set -x echo "${excludes[@]}" } run_backup /tmp/dummy/ /dummy "/tmp/dummy/save-ignored" "/tmp/dummy/save non'standard ignored" /tmp/toto /tmp/tata /tmp/tutu
但它不適用於包含引號的字元串(至少是簡單的引號)
/tmp/dummy/save-ignored /tmp/dummy/save non'standard ignored /tmp/toto /tmp/tata /tmp/tutu ++ echo --exclude /tmp/dummy/save-ignored --exclude /tmp/dummy/save 'non'\''standard' ignored --exclude /tmp/toto --exclude /tmp/tata --exclude /tmp/tutu --exclude /tmp/dummy/save-ignored --exclude /tmp/dummy/save non'standard ignored --exclude /tmp/toto --exclude /tmp/tata --exclude /tmp/tutu
使用數組而不是字元串。
例如:
opt=() opt+=(--exclude "first") opt+=(--exclude "another one") set -x echo "${opt[@]}"
這將正確處理空格(輸出):
+ echo --exclude first --exclude 'another one'
sudo rsync -azvh \ -e "ssh -p 22-i /home/backup/.ssh/mykey "\ --progress \ --delete \ ${excludes} \ ${source} \ unraid@69.69.69.69:$target }