UNIXではUNIXのコマンドやシェルの組み込みコマンドを用いてプログラムし、ユーザ が独自の便利な機能を作ることができる。これをシェルスクリプトあるいはシェル プログラムと呼ぶ。
シェルスクリプトの1行目は必ず例のように#!の次に使用するシェルを指定する。 2行目の#から始める行はコメントでシェルスクリプトのメモを書く。これは1行目 以外なら自由でなくても良い。実は1行目に#を書くと csh がログインシェルの場合 は csh が # でなければ sh(Bシェル、あるいは標準シェルとも呼ばれる)が選択される。 図5.52におけるシェルの指定方法は sh,csh 以外にも UNIX には沢山のシェルが存在する ので任意のシェルを選択するのに使う。3行目は本体で echo コマンドを使い、 ディスプレイに Good morning! と表示をする。表示をする文字列は ”で囲んで書く。 作成したシェルスクリプトを実行するためには次節で述べるようにファイルの属性を 実行可能に変更する必要がある。
{ kipces3 } 11% cat aisatu #! /bin/csh # Example of csh script echo "Good morning!" { kipces3 } 12%
図5.52 シェルスクリプトの簡単な例
この例のシェルスクリプトはディスプレイに文字を出力するが、キーボードから 入力することもできる。キーボードからの入力はシェルスクリプト内で $< と 書く事により行える。例を示す。
{ kipces3 } 13% chmod u+x aisatu { kipces3 } 14% ls -l aisatu -rwxr--r-- 1 matumoto 5 Sep 0 14:00 aisatu { kipces3 } 15% aisatu Good morning! { kipces3 } 16%
図5.53 シェルスクリプトの実行方法
4行目の echo コマンドで -n オプションを付けて実行することにより、通常の実行では 文字列を出力後に改行してしまうのを抑制している。5行目でキーボードからの入力を 変数nameに代入している。
{ kipces3 } 17% cat namedisp #! /bin/csh # Example of csh script echo -n "Input your first name : " set name=$ < echo "Hi, name$" { kipces3 } 18%
図5.54 キーボード入力のシェルスクリプト例
演習課題
条件、判定には if 文があり、以下のように記述する。
if 文の例を紹介する前に変数やコマンドの引き数について説明する。まず最初に変数 であるがこれにはユーザが定義する変数とシェルが起動されたときに設定される シェル変数の2種類がある。賢明な諸君は既に .cshrc というファイルの説明を思い 出していると思うが 「set path=(. /usr/ucb /bin .... ) とあるのはユーザ の入力したコマンドがどこにあるか探す際の順番を設定している。」とあるのはシェル 変数に set コマンドで値を設定していたのである(これからわかるように .login や .cshrc ファイルはシェルスクリプトの1種である)。この値は設定したシェルを使って いる限りシェルスクリプトの中で使用できる。値の設定の方法は
if (条件式) then コマンド1 コマンド2 : endif if (条件式) then コマンド1 else コマンド2 endif if (条件式1) then コマンド1 else if(条件式2) then コマンド2 : else コマンドN endif
この値を参照する場合は$変数と書けば変数の値を参照できる。次に引き数について説明する。 シェルスクリプトで必要な機能を持ったコマンドを作る際にファイル名などを引き数として 取り込むと便利な場合がある。Cシェルではシェルスクリプトが実行されると、コマンド自身は $0 に入り、引き数はシェル変数に順番に入る。コマンド名とその引き数を表示(エコーバック するという)するシェルプログラムは図5.55のようになる。
set 変数=値 set 変数=(値1 値2 値3 ・・・ )
シェルスクリプト disp の5行目の echo $#argev は引き数の数を表示している。 これで変数の引き数が理解できたので if コマンドを使ったシェルスクリプトの例を紹介する。
{ kipces3 } 1% cat disp #! /bin/csh echo $0 echo $argv[1] echo $argv[2] echo $#argev { kipces3 } 2% disp arg1 arg1 disp arg1 arg2 2 { kipces3 } 3%
図5.55 シェルスクリプトdisp
ここで新しいコマンド exitが使われているがこれはシェルスクリプトを 終了するときに使う。ここではコマンドの引き数が0(1個もない)の時は "You must type: filedisp filename" と表示し、スクリプトを終了するのに使われて いる。()内の条件式は論理和、論理積、否定が使える
{ kipces3 } 1% cat filedisp #! /bin/csh if ( $#argv == 0 ) then echo You must type: "$0 filename" exit else cat $argv[1] endif { kipces3 } 2% filedisp You must type: filedisp filename { kipces3 } 3%
図5.56 if thenを使ったシェルスクリプトの例
シェルスクリプト filedisp の2行目の $#argv == 0 は引き数の数が0と等しいか? と判定をしている。条件式で文字列や数字(整数値のみ)の大小を判断する条件式 には以下のようなものがある(条件式は真の時は1、偽の時は0を返す)。
論理和 条件式1 || 条件式2 論理積 条件式1 && 条件式2 否定 ! 条件式
そのほかにファイルに関する条件式があり、シェルスクリプトを作るときには非常に 有用である。
文字列1==文字列2 :等しい? 文字列1|=文字列2 :等しくない? 文字列1=~ パターン :パターンと一致? 文字列1!~ パターン :パターンと等しくない? 数字1>数字2 :数字1は数字2より大きいか? 数字1>=数字2 :数字1は数字2以上か? 数字1<数字2 :数字1は数字2より小さいか? 数字1>=数字2 :数字1は数字2以下?
シェルスクリプトで繰り返しを行う組み込みコマンドには foreach や while を使う。 最初にforeach組み込みコマンドを説明する。書き方は以下のように行う。
-e ファイル名 :ファイル名で指定したファイルが存在しているか? (UNIXでは通常のファイルの他に,ディレクトリや特殊ファイルもある。) -f ファイル名 :ファイル名で指定した通常のファイルが存在しているか? (普通のファイル,いわゆるplain fileであるかの判定をする。) -d ディレクトリ名 :ディレクトリ名で指定したディレクトリが存在しているか? -z ファイル名 :ファイル名で指定したファイルは空か? -r ファイル名 :ファイル名で指定したファイルは読み込みが可能か? -w ファイル名 :ファイル名で指定したファイルは書き込みが可能か? -x ファイル名 :ファイル名で指定したファイルは実行可能か?
指定されたディレクトリーにあるファイルのコピーをファイル名 .bak と言う名前で作る シェルスクリプトの例を示す。(図5.57)
foreach 変数名(引き数1 引き数2 ・・・・ 引き数N) コマンド1 コマンド2 : コマンドN end
ここで foreach の中で使用している fileコ マンドは引き数で指定されるファイルの型を 調べるコマンドで、この例では * によって指定されたディレクトリの全てのファイルを 調べている。 次に、while について述べる。while の書き方は以下のように行う。
{ kipces3 } 1% cat dispdir #! /bin/csh if ( $#argv == 0 ) then echo You must type: "$0 directry_name" exit else set dir = $argv[1] cd $dir foreach file ( * ) if (-f $file) $file > $file.bak end endif { kipces3 } 2% dispdir test { kipces3 } 3% cd test { kipces3 } 4% ls test1 test1.bak test2 test2.bak test3 test3.bak
図5.57 foreachを使ったシェルスクリプトの例
括弧内の条件式はこれまでに説明したものが使え、条件式を判断し、満足している間は end までのコマンドを繰り返す。条件式を判断した結果、最初から満足しない場合は コマンドを実行せずに end 以下のコマンドに移る。 while と同時に使うと便利なコマンド に shift コマンドがある。これは引き数で指定した変数をシフト、つまり順番に参照できる。 while とシフトを使った例を示す。(図5.58)
while (条件式) コマンド1 コマンド2 コマンド3 : end
この例は引き数で指定された数字の和を求めるシェルスクリプトで、csh ではこのよう に算術演算も可能である。3行目は和を格納する変数 sum の初期化で,文字でなく10進数 を変数に格納する場合は変数の前に1つ空白を置いて@を記述する.4行目では引数の数を 判定し、0になるまで while以下のコマンドを実行する。5行目は和の算術演算、6行目は引き数の シフトを行っている(shift により argv の引き数の番号が1つ増加し、残りの引き数の数が 1つ減少する)。
{ kipces3 } 1% cat suampro #! /bin/csh @ sum = 0 while ($#argv !=0) @ sum = $sum + $argv[1] shift argv end echo "SUM=$sum"
図5.58 whileとshiftを使ったシェルスクリプトの例
最後に異なるパターンの処理を行うのに便利な switch と case コマンドを紹介する。書き方は 以下の通り。
例を示す。(図5.59) この例のシェルスクリプトは "partcat オプション ファイル名" と入力 すると指定されたオプション、例えば -top が指定された場合は head コマンドを使って 指定されたファイルの先頭10行を、-bottom が指定された場合は tail コマンドを 使ってファイルの最後から10行を、そして -all が指定された場合は cat コマンドで ファイル全体を表示する物である。
switch (文字列) case パターン1 コマンド : breaksw case パターン1 コマンド : breaksw case パターン1 コマンド : breaksw default: コマンド : breaksw endswitch
演習課題
{ kipces3 } 1% cat partcat #! /bin/csh set file = $argv[2] switch ($argv[1]) case -top head $file breaksw case -bottom tail $file breaksw case -all cat $file breaksw default: echo "ERROR" endsw
図5.59 switchとcaseを使ったシェルスクリプトの例
CONTENTS |
BACK |