I isolated a problem in my script to this small example. That’s what I get:
$ cmd="test \"foo bar baz\""
$ for i in $cmd; do echo $i; done
test
"foo
bar
baz"
And that’s what I expected:
$ cmd="test \"foo bar baz\""
$ for i in $cmd; do echo $i; done
test
"foo bar baz"
How can I change my code to get the expected result?
UPDATE Maybe my first example was not good enough. I looked at the answer of Rob Davis, but I couldn’t apply the solution to my script. I tried to simplify my script to describe my problem better. This is the script:
#!/bin/bash
function foo {
echo $1
echo $2
}
bar="b c"
baz="a \"$bar\""
foo $baz
This it the expected output compared to the output of the script:
expected script
a a
"b c" "b
First, you’re asking the double-quotes around
foo bar bazto do two things simultaneously, and they can’t. You want them to group the three words together, and you want them to appear as literals. So you’ll need to introduce another pair.Second, parsing happens when you set
cmd, andcmdis set to a single string. You want to work with it as individual elements, so one solution is to use an array variable.shhas an array called@, but since you’re using bash you can just set yourcmdvariable to be an array.Also, to preserve spacing within an element, it’s a good idea to put double quotes around
$i. You’d see why if you put more than one space betweenfooandbar.See this question for more details on the special
"$@"or"${cmd[@]}"parsing feature of sh and bash, respectively.Update
Applying this idea to the update in your question, try setting
bazand callingfoolike this: