bash:在引号中处理引号

bash:在引号中处理引号,bash,escaping,quotes,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" 如何更改代码以获得预期结果? 更新也许我的第一个例子不够好。我看了罗布·戴维斯的答案,但

我将脚本中的一个问题隔离到这个小示例中。这就是我得到的:

$ 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"
如何更改代码以获得预期结果?
更新也许我的第一个例子不够好。我看了罗布·戴维斯的答案,但我无法将答案应用到我的剧本中。我试图简化我的脚本,以便更好地描述我的问题。以下是脚本:

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

bar="b c"

baz="a \"$bar\""
foo $baz
expected  script
a         a 
"b c"     "b
与脚本的输出相比,这是预期的输出:

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

bar="b c"

baz="a \"$bar\""
foo $baz
expected  script
a         a 
"b c"     "b

首先为什么要引用它

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

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

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

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

$ cmd=(test "\"foo bar baz\"")
$ for i in "${cmd[@]}"; do echo "$i"; done
有关sh和bash的特殊
“$@”
“${cmd[@]}”解析特性的详细信息,请参见

更新

将此想法应用到问题的更新中,尝试如下设置
baz
并调用
foo

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

如果我将值直接放入for循环中,这是可行的,但是如果我必须将值放入一个变量(如我的示例所示),该怎么办?看起来很好,适用于我的给定示例。不幸的是,我无法将此应用于我的原始脚本。我更新了问题,也许你可以看看。