
確實很難讓指令參數變數與 rsync 一起使用。我看到的行為是腳本中的錯誤:
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(601) [sender=3.0.7]
然而,腳本通過回顯輸出將要運行的命令,並將完全相同的命令副本粘貼到終端(或作為第一行返回到腳本中,並在其後退出)工作得很好?
執行此 rsync 的腳本程式碼(在本例中 check_flags 為空):
rsync_cmd=(${check_flags} -rWltpgoDvdHP --delete-before -- \"${backup_dir}\" \"admin@nas-1:${backup_basename}/\")
echo "CMD to run: rsync ${rsync_cmd[@]}"
rsync ${rsync_cmd[@]}
輸出:
CMD to run: rsync -rWltpgoDvdHP --delete-before -- "/share/CACHEDEV1_DATA/veeam_backup_daily/Daily backup _@1am__1" "admin@nas-1:/share/CACHEDEV1_DATA/veeam_backup_daily/"
我在網上讀到使用數組應該可以解決這個問題,但在這種情況下卻沒有。我相當確定這是一個簡單的解決辦法,但它讓我發瘋!
答案1
shell 在替換變數之前解析引號,因此在變數值中包含引號不會達到您的預期(並且這echo
是高度誤導的,因為它沒有顯示這種差異)。您應該做的是在定義數組時使用未轉義的引號(因此它們被解析為數組元素周圍的分隔符,而不是數組值的一部分),然後用雙引號引用對數組的引用(因此它不會出現單字-拆分或通配符擴展數組中的值)。我還將該echo
命令替換為printf
可以更準確地顯示將要發生的情況的命令:
rsync_cmd=(${check_flags} -rWltpgoDvdHP --delete-before -- "${backup_dir}" "admin@nas-1:${backup_basename}/")
printf "%q " CMD to run: rsync "${rsync_cmd[@]}"
printf "\n"
rsync "${rsync_cmd[@]}"
請注意,可能printf
不會顯示您所期望的內容 - 它會列印一個相等的將要執行的命令的表示形式,但每個參數有許多不同的等效表示形式,並且它會根據其偏好來選擇一個,而不是最初輸入的方式。順便說一句,您也可以用來set -x
調試這樣的東西,但是(與 一樣printf "%q "
)它可能使用與您預期不同的表示形式。