evalで文字列を変数として展開する

Bash,Shell

evalは文字列を式として評価するコマンドである。
文字列を変数として展開したり、関節参照する際に用いる。

スポンサーリンク

文字列を変数として展開する

例えば以下のような文字列をevalで展開してみる。

#!/bin/bash

eval 'val1=10 val2=sample'

echo $val1
echo $val2

すると、実行結果は以下のようになる。

username$ bash eval.sh 
10
sample

このように文字列の’val1=10 val2=sample’を、val1とval2という変数に展開してくれるため
echoを使って出力すると、値としての’10’と’sample’が出力される。

もちろん変数の中に格納されている文字列を展開することも可能で

#!/bin/bash

str='val1=10 val2=sample'

eval `echo $str`

echo $str
echo $val1
echo $val2

このコードの実行結果は

username$ bash eval.sh 
val1=10 val2=sample
10
sample

このようになる。

このevalの機能は、DBからクエリで引っ張ってきたデータを利用してCSVなどのデータを作成したり文字列を作成する際に役に立つ場面が結構ある。

例えばユーザーの個人情報を管理しているようなテーブル「user」があったとして、そこからユーザー名「name」カラムと電話番号「phone_num」カラムを利用して
nameさんの電話番号はphone_numです。
みたいな文字列を出力させたい場合は、shell scriptから実行するSQLでconcatを利用して

query_result=`mysql --defaults-extra-file=${db_config} -N ${db_name} -e "SELECT concat('name=', name), concat('phone_num=', phone_num) FROM user;"`

のように結果がname=XXX,phone_num=YYYの文字列として返ってくるようにクエリを発行する。

その後はquery_resultをevalで展開し、最終的に出力するための文字列を構築すれば良い。

eval echo $query_result
echo "${name}さんの電話番号は${phone_num}です。"

※userテーブルのレコードが1件の場合はこれで良いが、1件しかないテーブルは稀だと思うので、状況に応じてforでループが必要

スポンサーリンク

変数の二重展開(間接参照)

例えば変数の中の値が変数名を表している場合、間接的に参照して値を取り出すことができる。

#!/bin/bash

val1='val2'
val2='SAMPLE STRING'

eval echo \"\$$val1\"

このように書くことで、$val1の値の’val2’が”$val2″という文字列になるため、

eval echo "$val2"

と記述した場合と同じこととなる。
結果は以下

username$ bash eval.sh 
SAMPLE STRING

コメント

タイトルとURLをコピーしました