8762

[code]

    $ CMD="some_command abcdef"
    $ ${CMD}
    
[/code]

という命令を実行することは、単に

[code]

    $ some_command abcdef
    
[/code]

という命令を実行することと同様です。  
しかし、

[code]

    $ some_command "abc def"
    
[/code]

という命令を、冒頭の前者のように実行するにはどのようにしたら良いのでしょうか。  
仮に、

[code]

    $ CMD="some_command \"abc def\""
    $ ${CMD}
    
[/code]

という命令を実行した場合、`some_command`には`"abc`という引数と`def"`という引数の2つの引数が渡されたことになってしまいます。つまり、`"`を（BASHの構文としての）文字列を囲う記号としてではなく、文字列そのものとして認識してしまっているということです。

この方法において、`"abc def"`を1つの引数として命令を実行させることはできないでしょうか。

よろしくお願いします。


CC BY-SA 3.0
2015-04-04T04:26:45.937
8746
2015-04-04T09:27:06.090
8303
question
bash
BASHにおけるクォートを含む文字列の展開について


文字列をシェルの構文として認識させたいのであれば、これでどうでしょうか。

[code]

    $ CMD="some_command \"abc def\""
    $ sh -c "${CMD}"
    
[/code]


CC BY-SA 3.0
2015-04-04T05:01:50.787
8749
2015-04-04T05:01:50.787
3639
8746
answer


`eval` に引用符を評価させるのはいかがでしょう。

[code]

    $ CMD="some_command \"abc def\""  # some_command "abc def" が evalに渡される
    $ eval "${CMD}"
    
[/code]

この方法を用いる際、`$変数名` の展開なども行われるため、それを抑制したいならエスケープが必要ということに気を付けて下さい。

[code]

    $ x=foo
    $ CMD="echo \$x"     # echo $x が eval に渡される
    $ eval "${CMD}"
    foo                  # $x が展開される。
    $ CMD="echo \\\$x"
    $ eval "${CMD}"      # echo \$x が eval に渡される
    $x
    
[/code]


CC BY-SA 3.0
2015-04-04T05:13:38.540
8751
2015-04-04T05:22:22.940
2015-04-04T05:22:22.940
7831
7831
8746
answer


単一の変数にコマンドラインのすべてを含めて変数展開させて実行するのは、シェルの様々な解釈を厳密に理解しないと危険を伴ないます。推奨しません。`$CMD`
の内容に依りますが、`eval "$CMD"` も `sh -c "$CMD"` も、可能であれば避けたいです。

コマンドと引数を明確に分け、かつ個々の引数も明確に分けるだけであれば、配列変数を用いるほうが安全で確実です。

[code]

    $ CMDLINE=(some_command "abc def")
    $ "${CMDLINE[@]}"
    
[/code]

これは以下と等価です。

[code]

    $ some_command "abc def"
    
[/code]

`"${CMDLINE[@]}"` は `${CMDLINE[@]}` ではいけません。単一の配列変数名をダブルクォートで括り、添字 `@`
で展開する必要があります。これは、`"$@"` と `$@` の差と同様です。詳しくはマニュアルをどうぞ。解説が必要なら追記します。


CC BY-SA 3.0
2015-04-04T09:27:06.090
8762
2015-04-04T09:27:06.090
3061
8746
answer