質問: シェルの変数の格納・呼び出しについてお伺いさせていただきたく思います。 現在作成しているシェルは以下の三つに分かれています。 例 - **message.sh** ``` #!/bin/bash MSG001="001 処理開始" MSG002="002 処理終了" MSG004="003 ${cp_from}の${cp_to}へのコピーに失敗しました。" ... ``` ログなどに出力するメッセージを上記のような変数に格納してます。 **fnc.sh** ``` source message.sh # $1:コピー元 # $2:コピー先 # 失敗した場合ログに内容を出力 _glo_cp(){ cp_from=$1 cp_to=$2 cp -p $cp_from $cp_to if [[ $? -ne 0 ]]; then echo ${MSG004} > ./log.log fi ... ``` 共通関数ファイルです。上記にはざっくりとコピー用関数を書きました。 **run.sh** ``` #!/bin/bash source ./fnc.sh echo ${MSG001} > ./log.log # ファイルをコピー _glo_cp /from/cp_test.dum /to/cp_test.dum echo ${MSG002} > ./log.log ``` 実際に処理を行うシェルです。 共通関数を読み込んでから各処理を実行します。 質問 -- 実際に上記のようなファイルを作成し、実行してみたところ ログに書き出されていたメッセージは `003 のへのコピーに失敗しました。` と`_gro_cp`で記述していた変数が格納されていませんでした。 なぜこのような結果になってしまったのでしょうか? また、上記のような構成で正しくメッセージを出力したい場合はどのような記述の仕方をすればよろしいでしょうか。 質問内容について分かりづらいところなどありましたら申し訳ございません。 よろしくお願いいたします。
回答: > > なぜこのような結果になってしまったのでしょうか? > > > MSG004 変数への代入に「"」(ダブルクォーテーション)を使っているので、代入した時点(source message.sh 時点)で ${cp_from}, ${cp_to} が評価されます。 その時点では、${cp_from}, ${cp_to} は空なので、MSG004 の値は「003 のへのコピーに失敗しました。」となり、echo ${MSG04} でそのま出力されます。 > > また、上記のような構成で正しくメッセージを出力したい場合はどのような記述の仕方をすればよろしいでしょうか。 > > > まず、MSG004 変数への代入に「'」(シングルクォーテーション)を使います。 MSG004 の値は「003 ${cp_from}の${cp_to}へのコピーに失敗しました。」となります。 次に、echo ${MSG04} だと「${cp_from}」,「${cp_to}」そのまま表示されるので、`evel` で変数を評価するようにします。 ``` eval "echo ${MSG004}" >> ./log.log ``` なお、すべてのスクリプトで、「> .log.log」は「>> .log.log」と追記にした方がいいと思います。