2009年4月15日水曜日

eval command in bash shell script

シェルにevalコマンドっていうのがある、受け取った文字列を展開してそれを実行する、っていうイマイチよくわからない説明がよくされる。
それが、今回やっと理解出来たのでメモ

たとえば次の様な実行例
$ hoge="foo"; eval "echo $hoge"
foo
具体的にはどういう流れでこうなるのかというと、
evalは「echo $hoge」という文字列を受け取る。そして、文字列中の展開出来る箇所を展開する。
この場合は、シェル変数hogeにfooという文字列が入っているから、$hogeの部分はfooと展開される。
展開後にはその文字列が実行される。
$hogeはfooに展開されているから、実際に実行されるのは「echo foo」となる。
なので、表示結果は「foo」となったわけだ。

ところで、シェルスクリプトでは1次元配列しか扱えないのだけれど、
このevalを使うことで、2次元配列(多次元配列)を擬似的にだけれど、扱うことが出来る。

例として、3行3列の配列にランダムな値を入れていく。
#!/bin/sh

#declareコマンドでシェル変数iとjを整数値として生成。
#ただi=0とやると、0という文字を代入していることになってしまう。
declare -i i=0
declare -i j=0

#2重ループで、array_${i}_${j}の各要素にランダムな値を入れていく。
while [ $i -lt 3 ]
do
while [ $j -lt 3 ]
do
eval array_${i}_${j}=\$RANDOM
j=$j+1
done
j=0
i=$i+1
done

#各要素の内容を表示
i=0
j=0
while [ $i -lt 3 ]
do
while [ $j -lt 3 ]
do
eval echo array_${i}_${j}=\$array_${i}_${j}
j=$j+1
done
j=0
i=$i+1
done

結果
array_0_0=17314
array_0_1=30499
array_0_2=5518
array_1_0=19522
array_1_1=7919
array_1_2=2510
array_2_0=8634
array_2_1=31473
array_2_2=5638

「eval echo array_${i}_${j}=\$array_${i}_${j}」の行がわかりづらいので注釈。
 echo array_${i}_${j}=\$array_${i}_${j}
  ↓展開(i,jともに0の時点だとして)
 echo array_0_0=$array_0_0
表示結果は
array_0_0={要素[0][0]の数値}

それと、array_${i}_${j}のように、大括弧を入れて書くこと。
array_$i_$jでは、iの次のアンダーラインまで変数名の一部として展開しようとしてしまう。

0 件のコメント: