Bash字符串串联用于构建参数列表


12

鉴于这一点:

PARMS='-rvu'
PARMS+=" --delete --exclude='.git'"
echo $PARMS
rsync ${PARMS} . ${TARGET}

回显按预期显示PARMS字符串,不显示任何错误,但rsync默默地充当+ =添加的选项。但是,这按预期工作:

PARMS='-rvu'
rsync ${PARMS} --delete --exclude='.git' . ${TARGET}

我想我用bash引号搞砸了(这些引号总是有问题),但是即使字符串似乎已经正确构建,也不能完全确定忽略了什么以及为什么忽略了这些选项。


1
echo "$PARMS"rsync "${PARMS}"...
jasonwryan 2014年

这对我适用于bash4.2.25版,没有任何更改。
Anthon 2014年

Answers:


17

之间有一个区别:

PARMS+="... --exclude='.git'"

... --exclude='.git'

在第一个中,单引号本身就是引号,因此它们实际存在rsync作为参数提供的替代文本中。rsync获取一个值为的参数--exclude='.git'。在第二篇文章中,单引号在编写时由外壳程序解释,因为它们本身不在引号内,而是rsync可以看到--exclude=.git

在这种情况下,您根本不需要单引号- .git本身就是一个完全有效的shell字,没有特殊字符,因此您可以在命令中按字面值使用它。

对于这种事情,更好的是数组

PARMS=(-rvu)
PARMS+=(--delete --exclude='.git')
rsync "${PARMS[@]}"

这会将您的命令建立为单独的单词,并在编写数组行时提供您想解释的任何引号。即使参数本身包含特殊字符或空格,它也会作为单独的参数"${PARMS[@]}"扩展到数组中的每个条目,因此rsync可以看到您按原意编写的内容。


bash${PARMS}扩展后执行分词。因此,shell也解释了单引号。
cuonglm

2
尝试一下!是的 引号保持不变,如果它们之间有空格,则它们都是分割点。
2014年

@Gnouc:从bash的手册页:“引用删除:前面的扩展之后,人物的所有不带引号的出现\ '"。这并不能阻止上述扩张被删除的一个结果” “以上扩展”包括执行的扩展的参数扩展${PARMS}
卡姆(Camh)2014年

谢谢。因此,我知道在那种情况下,可以省略双引号内的单引号,但是出于完整性考虑,如果我需要引用一些特殊字符并且不想使用后一种方法,该怎么办?
neuviemeporte 2014年

如果您的特殊字符不属于IFS(通常为空格),则无需引用它们。如果是这样,除非您与eval他人一起破解,否则您将不走运。这通常有点不适当,而数组是处理它的正确方法。
Michael Homer 2014年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.