如何在bash变量中扩展变量而不扩展通配符?

9

我有一个变量包含了这样一种字符串:

var='$FOO/bar/baz*'

我希望用它的内容替换变量$FOO。但当我这样做时

var=$(eval "echo $var")

变量被替换了,但星号也被替换了,因此 var 现在包含文件系统中所有可能的匹配项(就像我在shell中按tab键一样)。例如,如果$FOO包含/home,则 var 将包含“/home/bar/baz1.sh /home/bar/baz2.sh /home/bar/baz.conf” 如何在不扩展通配符的情况下替换变量?

请参见http://mywiki.wooledge.org/TemplateFiles。 - Charles Duffy
如果你的目标是只禁用通配符,那么set -f可以实现。如果你的目标是进行安全的模板评估...呃,对于bash中的模板来说,并没有什么是“安全”的,因为你无法禁用命令替换;也就是说,一个包含$(rm -rf "$HOME")的模板将会执行该命令。 - Charles Duffy
2个回答

10

在bash中关闭globbing,然后重新启用它。

set -f 
var="$FOO/bar/baz*"
set +f

2

只需删除引号:

var=$FOO/bar/baz/*

变量赋值的右侧不会扩展通配符。

我提出这个建议时有些尴尬,但是怎么样: var ='$FOO / bar / baz *'; eval“expandedvar = $ var”(警告:eval 打开了许多错误的方式)。 - Gordon Davisson
我不确定为什么eval是必要的。在我的回答中, var的值将是“whateverwasinfoo/bar/baz/*”。变量$FOO被扩展了,但星号没有。我是否误解了问题? - chepner
这个回答不仅没有帮助(因为变量已经被设置为Godon和Kaidjin提到的那样),而且也是完全错误的。在变量赋值的右侧,Globs确实会被扩展。(至少在bash 3.2中是这样)例如:var=test.*; echo $var 结果:test.make test.sh test.txt 等等。 - drwatsoncode
1
Glob扩展只有在$var被扩展后才会发生。尝试使用echo "$var" - chepner
正如Charles Duffy在3年前指出的那样,没有安全的方法可以实现OP想要的功能。 - chepner
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接