rsync 排除在 shell 脚本中不起作用

rsync 排除在 shell 脚本中不起作用

我有这个 shell 脚本的最小工作示例,它不会排除缓存目录。

#!/bin/sh

SRC_DIR="/home/"
DEST_DIR="/backup/test"
OPTSTR="-avzHAXx --delete --exclude '.cache'"

rsync $OPTSTR $SRC_DIR $DEST_DIR

但是,如果你把它写成开放的,那么它就可以工作。

#!/bin/sh

rsync -avzHAXx --delete --exclude '.cache' /home/ /backup/test

有什么问题?

答案1

您的问题与您使用字符串的方式有关$OPTSTR。这是一个由多个空格分隔的单词组成的字符串,由于您使用它时不加引号,因此 shell 将其拆分为一个单独单词的列表。但是,shell 不会执行额外的引号删除步骤,因此字符串中的单引号将被文字。因此,您的命令排除名为 的文件和目录'.cache',而不是.cache。如果您需要使用其中包含空格或通配模式的字符串,您还会遇到问题。

简而言之:不要将需要分开的单独的东西放在一个字符串中。

相反,使用列表:

#!/bin/sh

src_dir=/home
dest_dir=/backup/test

set -- -v -a -x -HAX --delete --exclude='.cache/'

rsync "$@" "$src_dir/" "$dest_dir"

这会将位置参数列表设置为您稍后要与 一起使用的选项rsync。每个参数都会被正确处理,即使它包含带有嵌入空格和通配符的带引号的字符串,只要 的扩展$@是双引号的。

或者,如果您使用bash,您可以使用命名数组,

#!/bin/bash

src_dir=/home
dest_dir=/backup/test

opts=( -v -a -x -HAX --delete --exclude='.cache/' )

rsync "${opts[@]}" "$src_dir/" "$dest_dir"

还相关:

相关内容