![Rsync 忽略腳本中的雙引號](https://rvso.com/image/1684445/Rsync%20%E5%BF%BD%E7%95%A5%E8%85%B3%E6%9C%AC%E4%B8%AD%E7%9A%84%E9%9B%99%E5%BC%95%E8%99%9F.png)
當變數"$exclude_list"
被稱為參數時,rsync 會忽略雙引號,並以某種方式包含主資料夾,即使腳本中未提及。我嘗試將其包裹起來"${exclude_list}"
,但這也沒有幫助。
與 結合使用先前顯示變數的內容rsync
,表示它是正確的。
另一個奇怪的事情是,當我這樣做時,echo rsync ...
輸出是正確的並且沒有錯誤。
有問題的 bash 腳本的一部分:
echo "$exclude_list"
rsync -av --dry-run "$exclude_list" "$src" "$dest" >> /var/log/rsync.log || {
sendmail "Error: rsync failed for folder $src."; exit 1; }
輸出:
--exclude=lost+found
rsync: [sender] link_stat "/home/user/ --exclude=lost+found" failed: No such file or
directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at
main.c(1333) [sender=3.2.3]
這是 MCVE:
#!/bin/bash
# List of source folders
SRC_FOLDERS=(
[0]="/mnt/load-1/"
[1]="/mnt/load-2/"
)
# List of backup folders
DEST_FOLDERS=(
[0]="/mnt/load-1-b/"
[1]="/mnt/load-2-b/"
)
# List of folders to exclude during backup
EXCLUDE_FOLDERS=(
"lost+found"
"lost-found"
)
# Form the exclude list for rsync
for exclude_folder in "${EXCLUDE_FOLDERS[@]}"; do
exclude_list="$exclude_list --exclude=$exclude_folder"
done
# Loop through each folder pair
for i in "${!SRC_FOLDERS[@]}"; do
src=${SRC_FOLDERS[$i]}
dest=${DEST_FOLDERS[$i]}
rsync -av --dry-run "$exclude_list" "$src" "$dest"
done
答案1
問題在於
for exclude_folder in "${EXCLUDE_FOLDERS[@]}"; do exclude_list="$exclude_list --exclude=$exclude_folder" done
您迭代一個數組並從中EXCLUDE_FOLDERS
建立一個非數組變數。exclude_list
當稍後將其稱為 時"$exclude_list"
,shell 將其擴展為單字。
for
在循環exclude_list
為空之前。迴圈內的第一個賦值使變數以 開頭--exclude…
。注意前導空格。因為這個空間rsync
不承認這個字作為一個選項;它把它識別為相對路徑。我認為您目前的工作目錄是/home/user/
.因此,絕對路徑是/home/user/ --exclude=…
,這樣的檔案不存在,這就是錯誤所指出的。
即使前導空格不存在並且exclude_list
以某種方式創建為--exclude=… --exclude=…
,它仍然是錯誤的。"$exclude_list"
總是擴展為單字。您希望每個--exclude=…
都是 的單獨參數rsync
。
不引用$exclude_list
可能會起作用,但這是一個糟糕的解決方案;例如EXCLUDE_FOLDERS
如果 的元素包含空格、製表符或換行符(或觸發通配符的通配符),它將(或可能)失敗。
請閱讀我們如何運行儲存在變數中的命令?在 Bash 中,通常最好使用陣列。製作exclude_list
一個陣列:
for exclude_folder in "${EXCLUDE_FOLDERS[@]}"; do
exclude_list+=("--exclude=$exclude_folder")
done
然後在調用中rsync
使用"${exclude_list[@]}"
。