2012-04-26 13 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" 

は、どのように私は期待どおりの結果を得るために、私のコードを変更できますか?


更新多分私の最初の例は十分ではありませんでした。私は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

まず、あなたは、同時に2つのことを行うためにfoo bar bazの周りに二重引用符を求めている、と彼らがすることはできません。 3つの単語をグループ化してリテラルとして表示したいとします。だから別のペアを導入する必要があります。

第2に、cmdを設定し、cmdを1つの文字列に設定すると解析が行われます。個々の要素として扱いたいので、配列変数を使用する方法があります。 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

0

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

私はのためのループ内で値を直接置く場合、これは動作しますが、私の例のように変数に値を入れなければならないのですが? – multiholle