shの基本的な文法

 LinuxのBシェル(sh)でスクリプトを作成するための基本文法を紹介します。

●コメント行

 1文字目が「#」で始まる行はコメント行です*9。例えば,

はコメント行で,シェルはこの行の解釈・実行を行わずに無視します。ただし,「スクリプトの簡単な例」で示したように,スクリプトの1行目の記述

はコメントではありません。これは,スクリプトを解釈・実行するプログラム(すなわちシェル)を指定するためのものです。

●シェル変数の定義と参照

 前回は,シェル変数を紹介しましたが,スクリプトでもシェル変数を利用できます。シェル変数を使う場合にはまず,変数の名前を設定します。名前は,最初の文字が英字あるいは「_」*10で,2文字目以降は英字や「_」,または数字が使えます。


表1 あらかじめ役割が決まっている変数(一部)
[画像のクリックで拡大表示]

図2 if文の基本構文と図式表現
[画像のクリックで拡大表示]

表2 testコマンドで使える基本的な条件
[画像のクリックで拡大表示]

図3 ファイルの有無を確認する簡単なシェル・スクリプト
[画像のクリックで拡大表示]

図4 case文の基本構文
各コマンドの最後に「;;」を入力することを忘れないようにします。

[画像のクリックで拡大表示]

図5 while文の基本構文と図式表現
[画像のクリックで拡大表示]

図6 until文の基本構文
[画像のクリックで拡大表示]

図7 for文の基本構文
[画像のクリックで拡大表示]

図8 値に文字列を使った例
[画像のクリックで拡大表示]

 ただしシェルには,あらかじめ役割が決まっている変数があり,その変数の名前は利用できません。あらかじめ役割が決まっている変数の一部を表1[表示]に示します。

 シェル変数を新たに定義したい場合には,以下のように記述します。

変数名svar1を定義し,値「value1」を代入しています*11

 空白文字やメタキャラクタを含んだ文字列を代入したい場合には,「'」あるいは「"」で文字列を囲みます(本記事では,日本語を含む文字列も強調のため「'」で囲んでいます)。

 シェル変数を参照するには,変数名の前に「$」を付加します*12

●if文

 if文は構造化プログラミングの基本構造「選択」を記述します。if文では,条件コマンドを実行した結果として返される終了ステータスが,真(値0),あるいは偽(0以外の値)のいずれかにより,実行するコマンドを選択します。if文の基本構文とPADによる図式表現は,図2[表示]の通りです。

 「コマンド1」と「コマンド2」のそれぞれが,複数のコマンドであっても構いません。また,終了ステータスが偽の場合に,何もコマンドを実行させないことも可能です。この場合には,else文を記述しません。複数の条件コマンドを入れ子にすることもできます。その際は,elif文を利用します。

 「条件コマンド」の記述にはtestコマンドを使います*13。testコマンドでは,ファイルや文字列,数値の各条件をオプションで指定します。基本的な条件を表2[表示]に示します。testコマンドで指定するオプションを[ ]で囲んでも同じです。

 簡単な例を示すことにしましょう(図3[表示])。名前fileがカレント・ディレクトリに存在し,かつ通常ファイルならば「ファイル名fileは存在します。」と標準出力に出力し,存在しない,あるいは通常ファイルでなかった場合には「ファイル名fileは存在しません。」と標準出力に出力します。シェル変数fnameに「file」を定義しておき,if文ではこのシェル変数fnameを参照します。

●case文

 case文は選択の応用形です。if文では一つの条件が真か偽であるかを評価してコマンドを選択します。case文では,例えばシェル変数の値が,条件として指定した複数のパターンと等しい場合に各々別のコマンドを実行させるといったことが可能になります。

 例えば,値を比較するパターンが3通りあり,これらのパターンとすべて一致しなかった場合にも実行するコマンドがあるといった場合には,図4[表示]のような構文になります。指定したパターンとすべて一致しなかった場合に何も実行しないこともでき,この場合には「*)」の行を省略します。「コマンド1」などにはもちろん複数のコマンドを記述することができます。各コマンドの最後に「;;」を入力することを忘れないようにしましょう。

●while文

 while文は,構造化プログラミングの基本構造「反復」を記述します。while文では,条件コマンドを実行した結果として返される終了ステータスが真(値0)の間,コマンドを実行します(図5[表示])。この条件コマンドは,if文と同じものです。

●until文

 until文は反復の応用形です。条件コマンドの終了ステータスが真になるまで,コマンドの実行を繰り返します*14。基本構文を図6[表示]に示します。

●for文

 for文も反復の応用形で,問題向き反復,または回数指定反復とも呼ばれます。シェル変数に順番に値を代入してコマンドを実行します。値が3個ある場合の基本構文は図7[表示]のようになります。「値」が複数ある場合には,空白文字で区切ります。

 例として,シェル変数iに1から5までの値を代入し,反復回数を標準出力に表示する簡単なスクリプトを紹介します。

 さらに,文字列が値になる例を示します(図8[表示])。変数petに'チワワ','ダルメシアン','マルチーズ'の各値を代入し,「私は各犬が好きです」という意味のメッセージを標準出力に表示します。

●break文

 break文は,反復の終了条件を満たしていない途中に,反復から抜け出すときに利用します。while,until,forの各文に利用できます。break文があると,反復ブロックの終わりを表すdone文の次の文に実行が移ります。

●exit文

 exit文はスクリプトの実行を終了させます。スクリプトの途中にexit文があると,exit文以降のスクリプトは実行されません。

 これまでに示したスクリプト例では,exit文は使っていませんでした。exit文がなくても,スクリプトの最後の文(ステートメント)を実行すると自動的にシェル・スクリプトは終了します。Linuxではコマンドの実行終了時にそのコマンドが,どのような状態で実行を終えるのかを呼び出した側(例えばシェル)に値を返します(正常終了ならば値0,それ以外の終了は0以外の値になることが一般的です)。これが終了ステータスです。

 シェル・スクリプトもこの例外ではありません。exit文なしでスクリプトが実行を終了した場合には,スクリプトの終了ステータスは最後に実行したコマンドの終了ステータスとなります。

 exit文は,明示的にスクリプトの終了ステータスを定義するためにも利用できます。

正常にスクリプトが終了した場合,「終了ステータス」には値0を指定します。正常終了ではない場合には0以外の値になりますが,エラーの理由を特定できるように別途値を決めておき,エラー内容に基づいた値に設定しておくことが多いです。