シェルスクリプトの制御構造

制御構造について

シェルでもC言語・MELのようなif, while, switchなどが使用できる。
また、MELにおけるfor( in )のようなforeachもある。

ifの使用方法

以下のようにthen と endif がC言語・MELの { と } に対応すると思えば、大体C言語・MELと似ている。

  1. 条件が成り立てばコマンドの部分を実行。
    if(条件) then
        コマンド
    endif
    
  2. 条件が成り立てばコマンド1、成り立たなければ、コマンド2の部分を実行。
    if(条件) then
        コマンド1
    else
        コマンド2
    endif
    
  3. 条件1が成り立てばコマンド1、成り立たなければ、条件2を調べて成り立てばコマンド2の部分を実行。
    以下、同様にelse ifの条件を調べて成り立っていればその下のコマンドを実行。
    すべての条件が成り立たなければコマンドnを実行。
    if(条件1) then
        コマンド1
    else if(条件2) then
        コマンド2
           .
           .
    else
        コマンドn
    endif
    
  4. コマンドが1つだけの場合はthenendifが省略できる。
    if(条件) コマンド
    

ifの使用例1

まず、コマンドラインからifを色々と試してみる。
ここでは実行するコマンドの例としてechoコマンドを使用しているが、もちろんこのコマンド以外のコマンドも使用できる。

% set x = 3
% if($x > 1) echo test        ← 条件が成り立っているので
test                          ← コマンド(echo test)が実行される
% if($x + 2 > 1) echo test    ← 条件に数式を使う
test
% set y = 2.5
% if($y > 1.0) echo test      ← 条件に実数が使われていると
if: Badly formed number.      ← エラーになる
% set z = aaa
% if($z == "aaa") echo test   ← 文字列同士を比べる
test
% ls
test1.ma test2.ma
% set f = test1.ma
% if(-f $f) echo $f exist     ← test1.maが存在するかどうか調べてコマンドを実行
test1.ma exist
% set files = ( `ls *.mb` )
% if($#files > 0) echo test   ← *.mbファイルが1つ以上あればコマンドを実行
% cat test1.ma | wc -l        ← test1.maの行数を調べるコマンド
238                           ← test1.maの行数は238
% if(`cat test1.ma | wc -l` > 200) echo test    ← test1.maの行数が200以上であればコマンドを実行
test

ifの使用例2

次に、ifを使ってtest.maというデータファイルが存在していればMAYAでレンダリングするシェルスクリプトを作って実行してみよう。
レンダリングにはRenderコマンドを使用している。

  1. viで以下のシェルスクリプト(render.sh)を作る。
    set f = test.ma
    if(-f $f) then
    	Render -rd . $f
    endif
    
  2. 上のシェルスクリプトを実行すると以下のようになる。
    % ls
    render.sh test.ma
    % csh render.sh
    .......    ← test.maをレンダリング
    % ls
    render.sh test.1.iff test.2.iff test.3.iff test.ma
    % fcheck -n 1 3 1 test.@.iff    ← アニメーションのチェック
    %
    

while

シェルでもC言語のようなwhile文が使用できる。
シェルで使用するwhile文の形式は次の通り。

while(条件)
    コマンド
end

C言語・MELの { と } は無くて、そのかわり end が最期につく。
条件は if で紹介した条件と同じである。

whileの使用例

MAYAでレンダリングされた画像ファイル名を変換するシェルスクリプトを作ってみよう。
viで以下のシェルスクリプトをrename1.shという名前を作る。

set i = 1
while($i <= 3)
	mv test.$i.iff kadai.$i.iff
	@ i ++
end
上のシェルスクリプトを実行すると以下のようになる。

% ls
rename1.sh test.1.iff test.2.iff test.3.iff
% csh rename1.sh
% ls
rename1.sh kadai.1.iff kadai.2.iff kadai.3.iff
%

foreach

シェルではC言語には無い、foreach というループが使用できる。
MELでは似たものとして for( in ) がある。
特定の名前のファイルなどに対してコマンドを実行する場合などに便利である。
foreachではリストの中の要素を一つづつ変数に代入してコマンドを実行する。
リストの部分にはファイル名、変数(配列)やコマンドの結果(コマンド置換)などが使用できる。

foreach 変数 ( リスト )
    コマンド
end

foreachの使用例

下の例ではカレントディレクトリにあるJPEGフォーマットの画像ファイルをGIFフォーマットに変換している。 (フォーマット変換にはconvertコマンドを使用している。)

  1. 以下のシェルスクリプトをviによってconvert.shという名前で作る。
    foreach f (*.jpg)
    	convert $f $f:r.gif
    end
    
    $f:rはファイル名からピリオド以下の部分を取り去ったものになる。
    $fの中身がtmp.jpgだとすると$f:rはtmpになる。
    ($f:r.gifはtmp.gifになる)
    この:rのことを変数の修飾といい、:rの他に以下のものがある。
    :h
    パス名を取り出す。
    % set nn = /aaa/bbb.ccc
    % set n1 = $nn:h
    % echo $n1
    /aaa
    
    :e
    拡張子を取り出す。
    % set nn = /aaa/bbb.ccc
    % set n2 = $nn:e
    % echo $n2
    ccc
    
    :t
    ファイル名と拡張子を取り出す。
    % set nn = /aaa/bbb.ccc
    % set n3 = $nn:t
    % echo $n3
    bbb.ccc
    
  2. 以下のように実行してみる。
    % ls
    convert.sh kadai.jpg test.jpg tmp.jpg
    % csh convert.sh
    % ls
    convert.sh kadai.gif kadai.jpg test.gif test.jpg tmp.gif tmp.jpg
    %
    

上のforeachでは以下の様に処理が進む。

  1. foreach f (*.jpg)foreach f (kadai.jpg test.jpg tmp.jpg)と展開される。
  2. foreachによってset f = kadai.jpgが実行される。
  3. convert $f $f:r.gifによって convert kadai.jpg kadai.gifが実行される。
  4. foreachによってset f = test.jgpが実行される。
  5. convert $f $f:r.gifによって convert test.jgp test.gifが実行される。
  6. foreachによってset f = tmp.jpgが実行される。
  7. convert $f $f:r.gifによって convert tmp.jpg tmp.gifが実行される。

switch

シェルのswitch文はC言語のswitchに似ているが、もう少し柔軟な使い方ができる。
シェルで使用するswitch文の形式は以下の通り。

switch(変数)
	case 値1 :
	    コマンド1
	    breaksw
	case 値2 :
	    コマンド2
	    breaksw
	    .
	    .
	default :
	    コマンド
endsw

C言語の ように{ と } は無くて、そのかわり endsw が最期につく。
値1、値2...の部分には数値・文字列どちらでも使用できて、正規表現も使うことができる。
例えば、値の部分に*.cとあるとファイル名の最期の2文字が.cであるようなファイル(C言語プログラム)、*.m[ab]とあると最期の3文字が.maまたは.mbであるようなファイル名(MAYAデータファイル)になる。
実行される順番は以下の通り。

  1. 変数が値1にマッチするかどうか調べる。
  2. マッチすれば、コマンド1を実行して終り。
  3. マッチしなければ、次の値2にマッチするかどうか調べる。
  4. マッチすれば、コマンド2を実行して終り。
  5. 以下、同様にcaseの値とマッチしているかどうか調べていってマッチしている部分のコマンドを実行して終る。
  6. 全てのcaseの値にマッチしなければdefaultのコマンドを実行する。
    defaultは省略可能。

switchの使用例

画像ファイルの表示とMAYAのレンダリングを一つのプログラムで実行できるシェルスクリプトを作ってみよう。
以下のシェルスクリプトをviによってdo1.shというファイル名前で作る。

switch($argv[1])
	case *.iff :
		fcheck $argv[1]
		breaksw
	case *.ma :
		Render $argv[1]
		breaksw
endsw
上のシェルスクリプトを実行すると以下のようになる。
(サンプルデータkadai.maをホームディレクトリの下のunix2にダウンロード。)

% csh do1.sh kadai.ma
...   ← Render kadai.ma を実行
% csh do1.sh test.iff
...   ← fcheck test.iff を実行
% csh do1.sh kadai.sgi
%   ← 何も実行しない

練習課題

参考


Prev
Home | Contents
abe@injapan.net