注意:虽然下面的问题有特点rsync
,但它是不是一个关于 的问题rsync
;这是一个关于 zsh 数组的问题。
EXCLUDES
如果我像这样初始化变量
EXCLUDES=( --exclude=/foo --exclude=/bar --exclude=/baz )
然后,当我运行命令时
rsync -a $EXCLUDES / /some/target
...然后我看到/foo
, /bar
, 和/baz
确实没有复制到/some/target
.
但现在,假设EXCLUDE_ITEMS
是这样的
EXCLUDE_ITEMS=( /foo /bar /baz )
...我像这样初始化 EXCLUDE
EXCLUDES=()
for item in $EXCLUDE_ITEMS
do
EXCLUDES+=( "--exclude='$item'" )
done
...或者像这样
EXCLUDES=( $(for item in $EXCLUDE_ITEMS; do echo "--exclude='$item'"; done) )
...那么无论哪种情况,在我跑步之后
rsync -a $EXCLUDES / /some/target
...我现在发现排除的目录有不是被排除在转让之外。
EXCLUDES
由于命令行(在终端上输入的)都是相同的,因此我必须得出结论,显式初始化的命令行与通过迭代初始化的命令行之间存在差异EXCLUDE_ITEMS
,但我无法弄清楚它是什么。
如何EXCLUDE
从其中的项目进行初始化,EXCLUDE_ITEMS
以便在运行时后者确实被排除
rsync -a $EXCLUDES / /some/target
PS:事实上,如果我跑
eval "rsync -a $EXCLUDES / /some/target"
...whereEXCLUDES
已经以上面所示的基于循环的方式之一进行了初始化,那么确实会根据需要排除for
其中指定的目录。EXCLUDES
答案1
问题是,通过编写"--exclude='$item'"
,您将在排除模式中添加单引号。因此,您要排除'/foo'
等等,但您可能没有任何名称以单引号开头和结尾的文件。
你需要写
EXCLUDES+=( "--exclude=$item" )
或者,因为这是 zsh,所以不需要双引号:只需编写
EXCLUDES+=( --exclude=$item )
或者,由于这是 zsh,因此您不需要循环:只需使用^
参数扩展选项:
rsync -a --exclude=$^EXCLUDE_ITEMS …
在 ksh 或 bash 中,您将需要循环和双引号:
EXCLUDES=()
for item in "${EXCLUDE_ITEMS[@]}"; do
EXCLUDES+=( "--exclude=$item" )
done
rsync -a "${EXCLUDES[@]}" …