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[@]}"

相关内容