Rsync 忽略腳本中的雙引號

Rsync 忽略腳本中的雙引號

當變數"$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[@]}"

相關內容