扩展 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/
我尝试编写一个非常简单的同步脚本,它使用带有一些参数的 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/