シェルスクリプトの基本

シェルとは

ユーザはUNIXにコマンドという命令を与えることで様々な処理ができますが、 実はコマンドは直接UNIXというOS(Operating System:オペレーティングシステ ム)に渡されているわけではありません。

「シェル」とは、OSとユーザの間に存在するソフトウェアのようなものです。 コマンドを待ち受けるプロンプトの表示も、またワイルドカードを使用した入力 の処理(例えば、ls *.txt)も、実はシェルの機能の一部なのです。 シェル(shell)という言葉は「殻」という意味を持ち、核(カーネル:kernel) となるOSを包み込んで、ユーザからのコマンドをわかりやすくOSへ伝えたり、 OSからの結果をユーザへ表示したりする役割を担っています。

ここで皆さんが使用しているシェルの種類を確認するために、 setコマンドを使用します。setコマンドを単独 で使用すると、ユーザのシェル変数が表示されます。下記のように実行してみてく ださい。

% set | more
(表示結果の抜粋)
prompt  pc3240[susaki]!:%~%
prompt2 %R?
prompt3 CORRECT>%R (y|n|e|a)?
savehist        500
shell   /bin/tcsh
shlvl   1
sourced 1
status  0
tcsh    6.10.00

(または)

% set | grep shell
shell   /bin/tcsh

上記の内容から現在使用しているシェルは「/bin/tcsh」であ るとわかります。

UNIXのシェルには大きく分けて二つの系統があります。一つは「 sh」系統で、「sh」は 初期のUNIXに入っていたシェルで、現在もどのUNIXにも必ず入っています。 Linuxでは、このshを拡張した「bash」がよく使 われています。もう一つの系統は、「csh」 系統で、cshやtcshが有名です。みなさんもこのtcshを使っています。

どちらの系統も一長一短あるのですが、後述するシェルスクリプトを作成する際 には、sh系統が適切であると報告されています。ですので、今後、 シェルスクリプト作成の際には、bashを使用することとします。

ここで、シェルをbashへ変更させるために下記のように実行してみてください。

% bash
bash-2.05$

のように、プロンプトが「bash-2.05$」と変更されるはずです。 今後は、この「bash」というシェルを使用して説明していきます。

変数

変数と聞くとどのようなことを思い出すでしょうか?中学の数学では、

y = 3 x + 5

という一次関数を習ったと思います。ここで、xもyも変数といいます。xに3を代 入すればyは 3×3 + 5 = 14 という値をとります。

これから取り扱う変数というのは、上記のxのように「数 字や文字を代入するもの」と考えてください。数字の場合もありますし、 文字や文字列(文字のつながり)の場合もあります。

例えば、次のように入力してみてください。赤い表示が入力部分を指します。

bash-2.05$ name=susaki

これで変数「name」に「susaki」という文字列を代入したことになります。この nameという変数名は自分で自由に決めたものです。変数名は、アルファベットと 数字を用いて名前であれば、自分で自由に決められます。この変数の中身を 「echo」コマンドを使用して表示させると、

bash-2.05$ echo $name
susaki

と表示されます。ここで注意しなくてはいけないのは、変数は入力時には「name」 のように記述すれば良かったものの、それ以外では「 $name」のように$の記 号をつけなくてはならない、ということです。また状況によっては「${name}」と { }でくくる場合もあります。 どちらの表記方法も覚えておきましょう。

上記の例では文字列を変数に代入しましたが、数字を代入してみましょう。

bash-2.05$ a=10
bash-2.05$ echo $a
10

と、数字を代入しても問題ありません。今度は数字の和を計算させてみましょう。 下記のように入力して実行してみてください。

bash-2.05$ b=20
bash-2.05$ echo $a+$b
10+20

10と20の和である30という結果を表示させたかったのですが、「10+20」と表示 されました。単に文字列として$aと$bが処理されてしまったのです。

数値計算させるためには、下記のように入力します。

bash-2.05$ expr $a + $b
30

今度は望み通り「30」と表示されました。

数値計算における注意点

  1. 上記の数値計算において、$a  +  $bのように、演 算子(ここでは+)の前後にスペースを入れる必要がある。
  2. 乗算の場合は、$a  '*'  $bのように、 '  'でくくる必要がある。または\*としてもよい。
    bash-2.05$ expr $a * $b 
    expr: syntax error
    
    bash-2.05$ expr $a '*' $b 
    200
    
    bash-2.05$ expr $a \* $b 
    200
    
  3. 小数点を含む数字を除算する場合には、上記のexprを使用すると、エラーに なる。下記のように指定する必要がある。
    bash-2.05$ expr 20 / 10.3
    expr: non-numeric argument
    
    bash-2.05$ echo "scale=5; 20 / 10.3" | bc 
    1.94174
    
    「scale=数字」で、小数点以下の桁数を指定できる。

変数の練習問題

「date」コマンドを使用すると、現在の日にち、時刻を表示してくれる。

bash-2.05$ date
2002年  5月  7日 火曜日 23:02:51 JST

「date」コマンドには様々なオプションがあり、例えば、日にちのみ表示させる には

bash-2.05$ date +%d
07

のように、オプション「+%d」をつけるとよい。一部のオプションを下記 に紹介するが、その他のオプションを知りたい場合には「man date」で調べると 良い。

(月だけの表示)
bash-2.05$ date +%m
05
(年だけの表示)
bash-2.05$ date +%y
02
bash-2.05$ date +%Y
2002
(時刻だけの表示)
bash-2.05$ date +%T
23:08:32
  1. 現在の日にちを「day」という変数に代入するには、下記のように実行する。実 際に実行して確認せよ。
    bash-2.05$ day=`date +%d`
    bash-2.05$ echo $day
    07
    
  2. 上記にしたがって、月を「month」、年を「year」(2002と4桁の数字とする)、 時刻を「time」という変数に代入し、「echo」コマンドを使用して正しく代入されているか確認せよ。
    bash-2.05$ echo $day, $month, $year, $time
    07, 05, 2002, 23:19:47
    
  3. 上記の結果を利用して、下記のように表示させたい。********で隠された部 分を補い、実行して確認せよ。
    bash-2.05$ echo *****************
    2002/05/07-23:19:47
    

簡単なスクリプトの記述

上記の「変数」の説明では、コマンドラインでいちいち変数に値を入力したりし ましたが、ここでは複数の処理を一気に行わせるために、 スクリプトを作ります。下記の手順にしたがって、「test1-1.sh」という シェルスクリプトを作ってみましょう。

  1. まずbashがどこにあるのかを知らなければなりません。まだこのあたりの概念は 難しいかも知れませんが、次のように実行してみてください。
    bash-2.05$ which bash
    /bin/bash
    
    「bashという実行ファイルはどこにありますか?」とwhichコマンドを利用して 尋ね、その結果「/binの下にbashがあります」という返事をもらっています。こ の結果を後に使います。
  2. 次に、シェルスクリプトを書くためにエディタを立ち上げますが、 ここでは「emacs」を利用し、「test1-1.sh」というファイルに書くも のとします。コマンドラインで下記のように入力してください。
    bash-2.05$ emacs test1-1.sh
    すると、emacsというエディタが立ち上がります。自分の名字、名前に置き 換えた上で、下記の赤字の部分を入力して保存してください。emacsはUNIXでは 最もよく使われるエディタの一つで、今後もコンピュータリテラシーでは利用し ていきます。基本的な使い方は 大見先生のページに示されていますので参照してください。
    #!/bin/bash
    
    family=須崎
    name=純一
    echo "私の名字は${family}で、名前は${name}です。"
    
    
  3. 保存ができたら、emacsを終了してください。
  4. シェルスクリプトはただ書けばいいものではありません。 実行可能な形式に設定しなくては行けません。まずは、 下記のように「ls -al」で先ほど作ったtest1-1.shの パーミッションをみてみましょう。パーミッションについてよくわから ない人は、「chmod」のページを 参照してください。
    bash-2.05$ ls -al test1-1.sh
    -rw-r-----    1 susaki   teacher        38  5月  7 23:56 test1-1.sh
    
    実行可能な形式とは、パーミッションに「x」が表示されている状態ですが、上 記の表示結果には「x」が含まれていません。そこで、下記のように入力して実 行可能な形式に設定します。
    bash-2.05$ chmod +x test1-1.sh
    bash-2.05$ ls -al test1-1.sh
    -rwxr-----    1 susaki   teacher        38  5月  7 23:56 test1-1.sh
    
    「ls -al」で確認すると、今度は「x」が表示されています。これでシェルスク リプト「test1-1.sh」を実行するための準備が終わりました。
  5. 実行します。実行するときは、
    bash-2.05$ ./シェルスクリプト名
    のように、./を つける習慣をつけましょう。つけなくても実行できる環境設定の場合もあります が、それでもつけるようにしましょう。 実際に実行すると、
    bash-2.05$ ./test1-1.sh
    私の名字は須崎で、名前は純一です。
    
    と、正しく表示されました。

シェルスクリプトの練習問題

  1. 上記の「変数の練習問題」で取り扱った問題を参考にして、現在の日にちと 時刻を下記のように表示するスクリプトを「test1-2.sh」として作成し、 正しく表示されるか実行して確認せよ。
    bash-2.05$ ./test1-2.sh
    今日は2002年05月08日です。
    ただいまの時刻は08:54:30です。
    
    早く完了したものは、dateコマンドの様々なオプションを利用することで、スク リプトの記述内容も何通りか変わってくる。manコマンドでdateコマンドのオプ ションを調べ、別の記述方法を試してみよ。
  2. 上記の「変数の練習問題」で取り扱った問題を参考にして、現在の年齢を 設定し、10年後の年齢を表示させるスクリプトを作成したい。 下記のスクリプトのうち、********で隠された部分を補って、 「test1-3.sh」として作成し、 正しく表示されるか実行して確認せよ。
    (スクリプトの中身)
    #!/bin/bash
    
    age1=18
    age2=********************
    
    echo "私の現在の年齢は${age1}です。"
    echo "私の10年後の年齢は${age2}です。"
    
    
    (実行結果)
    bash-2.05$ ./test1-3.sh
    私の現在の年齢は18です。
    私の10年後の年齢は28です。
    
  3. 上記の「変数の練習問題」で取り扱った問題を参考にして、現在の年を dateコマンドを利用して変数にいれ、その変数を利用して 10年後の年を表示させるスクリプトを作成したい。 下記のスクリプトのうち、********で隠された部分を補って、 「test1-4.sh」として作成し、 正しく表示されるか実行して確認せよ。
    (スクリプトの中身)
    #!/bin/bash
    
    year1=********************
    year2=********************
    
    echo "現在${year1}年です。"
    echo "10年後は${year2}年です。"
    
    
    (実行結果)
    bash-2.05$ ./test1-4.sh
    現在2002年です。
    10年後は2012年です。
    

[2.シェルスクリプトの制御文] [3.シェルスクリプトの事例1] [4.シェルスクリプトの事例2]
[UNIXコマンドのページへ戻る] [須崎純一のページへ戻る]
須崎純一 京都大学大学 工学研究科都市環境工学専攻 環境情報学講座