2012-04-26 85 views
2

我在这个小例子的脚本中隔离了一个问题。这就是我得到:bash:用引号对待引号

$ cmd="test \"foo bar baz\"" 
$ for i in $cmd; do echo $i; done 
test 
"foo 
bar 
baz" 

而这正是我所料:

$ cmd="test \"foo bar baz\"" 
$ for i in $cmd; do echo $i; done 
test 
"foo bar baz" 

我怎样才能改变我的代码,以获得预期的结果?


UPDATE也许我的第一个例子不够好。我看了一下Rob Davis的回答,但我无法将解决方案应用到我的脚本中。我试图简化脚本来更好地描述我的问题。这是脚本:

#!/bin/bash 
function foo { 
    echo $1 
    echo $2 
} 

bar="b c" 

baz="a \"$bar\"" 
foo $baz 

这一点,预期产量相比脚本的输出:

expected script 
a   a 
"b c"  "b 

回答

2

首先,你要求foo bar baz左右的双引号同时做两件事,而他们不能。你希望他们把这三个词组合在一起,并且你希望它们以文字形式出现。所以你需要引入另一对。

其次,当您设置cmdcmd设置为单个字符串时,会发生解析。你想用它作为单独的元素,所以一个解决方案是使用一个数组变量。 sh有一个名为@的数组,但由于您使用的是bash,因此您可以将您的cmd变量设置为一个数组。

此外,为了保持元素内的间距,在$i周围放置双引号是个好主意。如果你在foobar之间放置了多个空格,你会明白为什么。

$ cmd=(test "\"foo bar baz\"") 
$ for i in "${cmd[@]}"; do echo "$i"; done 

上分别SH和bash,特殊"[email protected]""${cmd[@]}"解析功能的更多详细信息,请参见this question

更新

将这一想法在你的问题的更新,请尝试将baz并调用foo这样的:

$ baz=(a "\"$bar\"") 
$ foo "${baz[@]}" 
+0

看起来不错,适用于我举的例子。不幸的是,我不能将它应用到我的原始脚本。我更新了这个问题,也许你可以看看这个问题。 – multiholle 2012-04-26 20:39:52

0

为什么摆在首位报价呢?

for i in test "foo bar baz"; do echo $i; done 
+0

这工作,如果我直接把值在for循环,但如果我必须将值放入像我的示例中那样的变量,该怎么办? – multiholle 2012-04-26 18:28:56