Shell 如果没有响应,则引用壳牌glob结果

Shell 如果没有响应,则引用壳牌glob结果,shell,substring,glob,quote,Shell,Substring,Glob,Quote,我想像这样使用rsync: EXCLUDES=('*~' '*.cfg') rsync ${EXCLUDES[@]/#/--exclude=} SOURCE DEST $ shopt -s nullglob $ EXCLUDES=(*~ *.cfg) $ echo rsync "${EXCLUDES[@]/#/--exclude=}" SOURCE DEST rsync SOURCE DEST 预期结果是: rsync --exclude=*~ --exclude=*.cfg SOURCE

我想像这样使用rsync:

EXCLUDES=('*~' '*.cfg')
rsync ${EXCLUDES[@]/#/--exclude=} SOURCE DEST
$ shopt -s nullglob
$ EXCLUDES=(*~ *.cfg)
$ echo rsync "${EXCLUDES[@]/#/--exclude=}" SOURCE DEST
rsync SOURCE DEST
预期结果是:

rsync --exclude=*~ --exclude=*.cfg SOURCE DEST
rsync '--exclude=*~' '--exclude=*.cfg' SOURCE DEST
但glob没有结果时的结果是:

rsync --exclude=*~ --exclude=*.cfg SOURCE DEST
rsync '--exclude=*~' '--exclude=*.cfg' SOURCE DEST

我被一行解决方案${EXCLUDES[@]/-exclude=}迷住了。如何防止全局扩展引用结果?或者是另一种单线解决方案?

我可以复制您这样描述的行为:

$ touch a~ b~ c.cfg
$ EXCLUDES=('*~' '*.cfg')
$ echo rsync ${EXCLUDES[@]/#/--exclude=} SOURCE DEST
rsync --exclude=*~ --exclude=*.cfg SOURCE DEST
如果我理解您提出的问题,那么您希望扩展排除的文件名。在这种情况下,请使用:

$ EXCLUDES=(*~ *.cfg)
$ echo rsync "${EXCLUDES[@]/#/--exclude=}" SOURCE DEST
rsync --exclude=a~ --exclude=b~ --exclude=c.cfg SOURCE DEST
或者,当没有匹配的文件时,您可能会担心输出中的glob,例如:

$ rm -f a~ b~ c.cfg
$ EXCLUDES=(*~ *.cfg)
$ echo rsync "${EXCLUDES[@]/#/--exclude=}" SOURCE DEST
rsync --exclude=*~ --exclude=*.cfg SOURCE DEST
要防止出现这些全局变量,请如下使用nullglob:

EXCLUDES=('*~' '*.cfg')
rsync ${EXCLUDES[@]/#/--exclude=} SOURCE DEST
$ shopt -s nullglob
$ EXCLUDES=(*~ *.cfg)
$ echo rsync "${EXCLUDES[@]/#/--exclude=}" SOURCE DEST
rsync SOURCE DEST
nullglob导致不匹配的glob消失

注释

使用EXCLUDES='*~'*.cfg'时,不会进行任何扩展,因为全局变量在引号中。如果要展开,请删除引号

数组扩展${EXCLUDES[@]/-exclude=}应该用双引号引起来。如果没有双引号,将对结果执行分词,如果任何文件名包含空格,将导致错误


你认为为什么会有引用?这是set-x输出吗?你能给出程序输出方面的预期和实际结果,而不是你认为应该等同于但认为不是的命令方面的结果吗?或者至少是什么让你相信?如何防止glob扩展以引用结果?这个问题还不清楚。请详细说明。