Backup of UNIX/コマンド/シェル・シェル組み込み/eval(No. 4)
- Backup list
- View the diff.
- View the diff current.
- View the diff for visual.
- View the source.
- Go to UNIX/コマンド/シェル・シェル組み込み/eval.
- 0 (1970-01-01 (Thu) 09:00:00)
- 1 (2006-06-01 (Thu) 23:30:14)
- 2 (2006-12-29 (Fri) 23:14:23)
- 3 (2006-12-30 (Sat) 00:23:54)
- 4 (2006-12-30 (Sat) 00:25:02)
- 5 (2006-12-30 (Sat) 01:26:29)
- 6 (2006-12-30 (Sat) 11:21:13)
- 7 (2006-12-30 (Sat) 13:37:42)
- 8 (2007-01-15 (Mon) 07:33:22)
- 9 (2007-01-17 (Wed) 11:47:45)
- 10 (2009-10-20 (Tue) 22:40:57)
引数とした文字列をコマンドと解釈して実行します。
例 
たとえば
% eval cd /
とすれば cd / を実行します。"cd /" のようにしたほうが安全かもしれません。 引数の文字列は複数個でもかまいません。連結して実行されます。
正確にはevalは引数を一度「評価」し、それらを改めてコマンドとして実行します。「評価」とは変数を展開することです。
% set x='ls -d $HOME' (csh, tcsh の場合) % $x ls: $HOME: No such file or directory
シングルクォーテーションの場合、変数は展開されずに格納されるため、 $HOME という文字として扱われている。
% eval $x /home/student/s1080134
$HOME を展開してくれている。
シェルスクリプト内での使用 
eval はシェルスクリプト内で良く使われます。
#!/bin/bash num=1 while [ $num -le $# ] ; do eval echo "Argument $num is \$$num" num=`expr $num + 1` done
この
eval echo "Argument $num is \$$num"
の部分は eval によって
echo "Argument 1 is $1"
のように置き換えられこのコマンドが実行されます。
% bash [このシェルスクリプトファイル] a b c
のようにして試してみてください。 sh, bash スクリプトでは $1 が第一引数、$2 が第二引数を、以下略を意味します。 よって、
Argument 1 is a Argument 2 is b Argument 3 is c
のようになるはずです。
一応ついでに説明しておきますと、$# が引数の数で、-le は less or equal (<=) を意味します。
find との併用 
自分はコマンドラインでは例えば find コマンドを使用してなにか行うときにいきなり exec するとこわいので、まず
find -exec echo "コマンド ;" \;
のように echo で実験をしてから
eval `find -exec echo "コマンド ;" \;`
のように実行したりします。` ` で ` ` 内のコマンドの出力を他のコマンドの引数とすることができます。 ミソは
echo "コマンド ;"
の ; (セミコロン) で、これをつけておかないと、例えば特に意味はないですが
ls [file1] ls [file2] ls [file3]
という実行を期待して
eval `find -exec echo "ls {}" \;`
のようにしてしまうと、
ls [file1] ls [file2] ls [file3]
eval `find -exec echo "ls {}; " \;`
ならば
ls [file1]; ls [file2]; ls [file3]
のように ; でコマンドが区切られるので期待通りの動作をします。便利な例としては
% eval `find -exec echo "sed 's/[regexp]/[string]/g' {} > /tmp/tmp; \mv /tmp/tmp {};" \;`
こんなのいかがでしょうか?カレントディレクトリ以下のすべてのファイル中の文字列を置き換えます。
最後にまた、シェル変数を使用しようとすると一度展開されてしまうことを忘れずに。 コマンドラインではそうそうシェル変数を使用しないと思いますが、たまにはまります。
2段評価 
% eval echo 'ls -d \$HOME' ls -d /home/student/1080134
とすれば変数を評価した結果の文字列を得ることができるので、 その後また eval すれば2段評価になりますね。 この例だと2回目に変数がないですが。
役に立たなかった場合コメントをお願いします。
- 書き直してみました。 -- s1080134 2004-05-29 (土) 16:24:08
- 利用価値がわかりません。 -- 2004-05-29 (土) 00:03:05