扩展 Bash 中的变量作为 rsync 的参数

Expanding a variable in Bash as a parameter to rsync

我尝试编写一个非常简单的同步脚本,它使用带有一些参数的 rsync。 我希望这些参数存储在我的脚本中的一个变量中。 这是一个最小的例子:

$tree
.
├── a
│   └── aaa_p=1_k=1
│       └── x.txt
├── b
│   └── aaa_p=1_k=1
│       └── x.txt
└── script.sh

$cat script.sh

#!/bin/bash

PARAMS="--exclude '*p=*'"
rsync -av ${PARAMS} ./a/* ./b/

但是当我 运行 script.sh 时,它会同步 x.txt,尽管 x.txt 它驻留在包含 p= 的路径中,该路径应该被排除。同时,当我从命令行 运行 时: rsync -av --exclude '*p=*' ./a/* ./b/ 然后 exclude 得到尊重,同步不会发生。

我在脚本中做错了什么,所以没有考虑到 exclude 开关?是Bash中的变量替换吗?

当您在终端中键入 --exclude '*p=*' ./a/* ./b/ 时,' 引号会被 bash 删除。 rsync 只看到字符串 *p=*。但是当你写 PARAMS="--exclude '*p=*'"; rsync -av ${PARAMS} 时,变量中的引号会保留下来,告诉 rsync 排除以 '.

开头和结尾的文件

您可以省略变量内的 ' 引号,但是 * 会在 rsync 运行之前扩展(以前也是这种情况,但是 '*p*'可能不匹配任何文件)。您可以引用 "$PARAMS" 以避免扩展 *,但是整个字符串 --exclude *p=* 将被视为一个参数。

解决这个问题的正确方法是使用数组:

params=(--exclude '*p=*')
rsync -av "${params[@]}" ./a/* ./b/