bash:用引号处理引号

时间:2012-04-26 17:47:52

标签: bash escaping quotes

我将脚本中的问题与这个小例子隔离开来。这就是我得到的:

$ 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"

如何更改代码以获得预期结果?

<小时/> 更新也许我的第一个例子还不够好。我查看了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 个答案:

答案 0 :(得分:2)

首先,你要求foo bar baz周围的双引号同时做两件事,但他们不能。您希望他们将这三个单词组合在一起,并希望它们显示为文字。所以你需要引入另一对。

其次,当您设置cmd并且cmd设置为单个字符串时,会发生解析。您希望将其作为单个元素使用,因此一种解决方案是使用数组变量。 sh有一个名为@的数组,但由于您正在使用bash,因此您可以将cmd变量设置为数组。

另外,为了保留元素中的间距,最好在$i周围加上双引号。如果您在foobar之间放置多个空格,就会明白为什么。

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

有关sh和bash的特殊"$@""${cmd[@]}"解析功能的详细信息,请参阅this question

<强>更新

将此想法应用于您问题中的更新,请尝试设置baz并像这样调用foo

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

答案 1 :(得分:0)

为什么首先引用它?

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