Korn――高機能なシェルBeginner's Guide(2/3 ページ)

» 2008年05月13日 10時00分 公開
[Mark-Alexander-Bain,Open Tech Press]
SourceForge.JP Magazine

組み込み算術式

 bashで何らかの算術演算をしようとすれば、「answer=$( echo 1.5 + 1.7 | bc )」や「answer=$( echo 1.5 1.7 | awk '{print $1 + $2 }' )」などのような形で間接的に実行するしかない。しかしKornシェルの場合には直接的に「answer=$(( 1.5 + 1.7 ))」や「((answer = 1.5 + 1.7 ))」というように記述できる。

 この機能はabs、acos、asin、atan、cos、cosh、exp、int、log、sin、sinh、sqrt、tan、tanhなどの数学関数と一緒に利用できる。従って例えば「(( pi = 4.0 * ( 4.0 * atan(1.0/5.0) - atan(1.0/239.0) ) ))」という式で、非常に精度の高いπの値を持つ変数(pi)を作成できる。なおこの場合、piの値は3.14159265358979324になる。

複合変数

 前記で、πの値を持つ変数を作成する方法を紹介した。ここではKornシェルとこの変数piを使って、円を表わすのに使用する変数を考えてみよう。

> radius=30

> (( circumference = 2 * pi * radius ))

> (( area = pi * radius * radius ))


 見て分かる通り、変数を使用する際に「$」記号を使用する必要はない(使いたいなら使ってもよいが、使う必要はない)。この式では、変数circumferenceの値は188.495559215387594、変数areaの値は2827.43338823081392になる。

 次に、各変数名の前に例えば「circle_」という文字をつけ足して、これらの変数をグループ化したいという場合について考えてみよう。Kornシェルでは、「複合変数」という単一の変数を用いてそれを行うことができる。

> circle=

> circle.radius=30

> (( circle.circumference = 2 * pi * circle.radius ))

> (( circle.area = pi * circle.radius * circle.radius ))


 このテクニックは変数を整理整頓するのに役立つだけではなくて、多くのプログラミング言語にあるような構造体やレコードを作成するために使用することもできる。

> driverx=(

name=""

float wage=145.50

integer travel_radius=50


 前記では、構造体として複合変数を定義して、各フィールドのデータ型を定義して、おのおのにデフォルトの値を代入している。以下では、この構造体を使って複数のレコードを作成している。

> eval "driver01=$driverx"

> driver01.name="Bill"

> eval "driver02=$driverx"

> driver02.name="Fred"

> (( driver02.wage = ${driverx.wage} * 1.10 )) # Fredの給料を上げる

> print "${driver01.name} \$${driver01.wage} ${driver01.travel_radius} miles"

Bill $145.50 50 miles

> print "${driver02.name} \$${driver02.wage} ${driver02.travel_radius} miles"

Fred $160.05 50 miles


ディシプリン関数

 Kornシェルでは、単一の変数に複数の値を割り当てることができるだけでなく、単一の変数に複数の関数(Kornシェルではディシプリン関数と呼ばれる)を関連づけることもできる

 Kornシェルの変数には、3つのディシプリン関数を関連づけることができる。すなわちget、set、unsetの3つで、それぞれ変数が読み取られるとき、書き込まれるとき、削除されるときに実行される。これらのディシプリン関数は、直接的には何も出力しないという、そのほかのシェル関数とは大きく異なる点がある。そこで「.sh.value」というKornシェルの特殊変数を利用する必要がある。ディシプリン関数の中で.sh.valueの値が変更されると、それによって変数の値が変わる。従って例えば、ディシプリン関数を使って円周を計算するメソッドは次のようになる。

> function circle.circumference.get {

(( .sh.value = 2 * pi * circle.radius ))

}


 この関数は、現在使用中のシェル上で利用するためにコマンドラインで定義することもできるし、スクリプトファイルの中に書いておくこともできる。そのどちらかをしておけば、後は変数circle.radiusに半径の値を代入するだけで変数circle.circumferenceに円周の値を求めることができる。

> circle.radius=1

> echo ${circle.circumference}

6.28318530717958648

> circle.radius=20

> echo ${circle.circumference}

125.66370614359173


 これができれば、circle.area、circle.circumference、circle.radiusの3つの変数だけを使って、半径を入力すれば円の面積と円周を求めることができる関数、円周を入力すれば面積と半径を求めることができる関数、面積を入力すれば円周と半径を求めることができる関数などを作成することも簡単にできるだろう。

 それでは次に、おそらく他では見たことがない、しかしきっと便利に感じるであろう機能――コプロセス――を紹介する。

Copyright © 2010 OSDN Corporation, All Rights Reserved.

注目のテーマ