通过数组变量向程序传递参数

通过数组变量向程序传递参数

注意:虽然下面的问题有特点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[@]}" …

相关内容