BASHにおけるクォートを含む文字列の展開について

投稿者: Anonymous
$ CMD="some_command abcdef"
$ ${CMD}

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

$ some_command abcdef

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

$ some_command "abc def"

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

$ CMD="some_command "abc def""
$ ${CMD}

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

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

よろしくお願いします。

解決

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

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

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

これは以下と等価です。

$ some_command "abc def"

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

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *