我的目标是让我的 bash 脚本运行此命令:
rsync -azhi --dry-run --exclude={'file1.txt','file2.txt','*.sql'} /from-directory/ /to-directory/
...当这样抽象时:
srcdir='/from-directory/'
dstdir='/to-directory/'
excludes="{'file1.txt','file2.txt','*.sql'}"
rsync -azhi --dry-run --exclude="$excludes" "$srcdir" "$dstdir"
$srcdir
并$dstdir
正确评估,但$excludes
没有像我希望的那样被解释。在命令行中, --exclude={'file1.txt','file2.txt','*.sql'} 效果很好。但是一旦我尝试将 {...} 字符串填充到变量中,它就会停止工作。
答案1
尝试使用数组。例如:
excludes=(file1.txt file2.txt '*.sql')
rsync -azhi --dry-run $(printf -- "--exclude=%q " "${excludes[@]}") /from-directory/ /to-directory/
顺便说一句,如果您这样做,请不要*.sql
用单引号引起来想它将扩展到当前目录中的所有 .sql 文件。我猜这不是你想要的,所以我引用了它。
这将扩展到:
rsync -azhi --dry-run --exclude=file1.txt --exclude=file2.txt --exclude=*.sql /from-directory/ /to-directory/
或者:
rsync -azhi --dry-run --exclude="$(printf -- "%q," "${excludes[@]}" |
sed -e s/,$//)" /from-directory/ /to-directory/
将扩展到:
rsync -azhi --dry-run --exclude=file1.txt,file2.txt,*.sql /from-directory/ /to-directory/
答案2
与rc
和 导数 或zsh -o rcexpandparam
:
excludes=(file1.txt file2.txt '*.sql')
rsync -azhi --dry-run '--exclude=- '$excludes $srcdir $dstdir
和fish
:
set excludes file1.txt file2.txt '*.sql'
rsync -azhi --dry-run '--exclude=- '$excludes $srcdir $dstdir
和zsh
:
excludes=(file1.txt file2.txt '*.sql')
rsync -azhi --dry-run '--exclude=- '$^excludes $srcdir $dstdir
(其中为该数组扩展^
启用rc
-style 扩展)。
和ksh93
/ bash
/ zsh
:
excludes=(file1.txt file2.txt '*.sql')
rsync -azhi --dry-run "${excludes[@]/#/--exclude=- }" "$srcdir" "$dstdir"
请注意,我们使用'--exclude=- '
代替,否则,如果有一些模式,例如,或,--exclude=
它将不起作用。请参阅手册页(强调我的):$excludes
- *
+ *
!
rsync
--排除=模式 该选项是 --filter 选项的简化形式 默认为排除规则并且 不允许完全 普通过滤规则的规则解析语法。 [...] 请注意,--include/--exclude 命令行选项不允许 如上所述的全方位规则解析——它们仅 允许 包含/排除模式的规范加上“!”令牌来清除 列表(以及从文件读取规则时的正常注释解析)。 如果模式不是以“-”(破折号、空格)或“+”(加号、 空格),那么该规则将被解释为“+”(对于包含 选项)或“-”(对于排除选项)作为字符串的前缀。 A 另一方面,--filter 选项必须始终包含一个短 或规则开头的长规则名称。