Lesson 13
シェルスクリプトを利用してプログラミングをしてみよう
目次
Lesson 13
Chapter 1
はじめに
このレッスンではシェルスクリプトと呼ばれる、シェルが理解できる命令文を集めたプログラムを実際に書いて、出力結果を確認するところまで学んでいきます。 これらをマスターすることで、普段GUIにて行っている操作などをコマンドで行ったり、システムの細かい設定などをすることが出来るようになります。まずはシェルの概念から学んでいきましょう。
シェルとは
シェルとは、OSの中核となるシステム(カーネル)とユーザーの間で命令のやり取りをサポートするものです。主にユーザーからの入力を解釈し、コンピューターの機能を実行するためのコマンドを受け取ります。 また、シェルにはいくつか種類がありますが、最も一般的なものはUNIXシェルで```Bash```,```Zsh```,```Ksh```などがあります。
シェルスクリプトとは
シェルスクリプトとはシェルが解釈できるコマンドを記述したスクリプトファイルのことです。シェルスクリプトを実行すると、ファイル記述されたコマンドが上から順番に実行されます。 シェルスクリプトを使用することで、複数のコマンドをまとめて実行することができたり、複数のコマンドを繰り返し実行することが出来るといったメリットがあります。
シェルスクリプトの実行方法はいくつかありますが、基本的には以下のコマンドで実行できます。
$ ./[ファイル(シェルスクリプト)名]
では実際に、具体的なシェルスクリプトの記述方法や実行方法について学習していきましょう。

Lesson 13
Chapter 2
パラメータを受け取ってみよう
シェルスクリプト実行時にパラメータ(引数)と呼ばれる値を、シェルスクリプト自身に渡して実行することが出来ます。
例として、sample.sh
というシェルスクリプトファイルに"Hello"という文字列をパラメータとして渡して実行するコマンドは以下の通りです。
$ ./sample.sh Hello
また、2つ以上のパラメータを同時に渡すことも可能です。
$ ./sample.sh Hello Bye 999
ここでは"Hello", "Bye", "999"をそれぞれ半角スペースで区切ることで、3つのパラメータを渡していることが分かります。 次のチャプターでは、実際に渡したパラメータをシェルスクリプトで利用するための記述について学んでいきます。

Lesson 13
Chapter 3
標準出力でシェルスクリプトの実行結果を見てみよう
標準出力とは、コンピューターで実行されるプログラムやコマンドが出力する、標準的な出力先のことです。通常、コマンドを実行している環境であるコンソールやターミナルウィンドウに出力されます。
シェルスクリプトではecho(エコー)
コマンドを使用することで標準出力を利用して任意のテキストをコンソールに表示することが出来ます。
以下は"Hello World"というテキストを標準出力するシェルスクリプトです。
#!/bin/bash
echo "Hello World"
では次に、受け取ったパラメータを標準出力するhello.sh
というシェルスクリプトを書いていきます。
#!/bin/bash
echo $1
このように1番目に渡されたパラメータは$1
と記述することで呼び出すことが出来ます。また、$2
とした場合2番目のパラメータを呼び出すことになります。
このシェルスクリプトに"Hello"というパラメータを渡して実行すると以下の様になります。
$ ./hello.sh Hello
Hello
こうして、パラメータとして渡した"Hello"という文字列が出力結果として表示することが出来ます。

Lesson 13
Chapter 4
変数を使用して値を保存してみよう
変数とは、プログラムやスクリプトで使用される、値(データ)を保存するための箱のような物です。パラメータをスクリプト内で使用する際に記述した$1
なども変数と言えます。
シェルスクリプト内で変数を定義するには以下のような記述をします。
変数名=値
例として"Hello World!"といった文字列をtext
という変数に格納してみます。
text="Hello World!"
このように変数定義をすることで以後、$text
という記述をするだけでHello World!
という文字列を呼び出すことが出来ます。
まとめると、変数を利用した"Hello World!"を標準出力するシェルスクリプトは以下のようになります。
#!/bin/bash
text="Hello World!"
echo $text
これが変数の基本的な使用方法となります。何度も頻出する値などは、変数を利用することで、その値に変化があった場合に変数定義の箇所のみを編集するだけで全体に反映されるといったメリットなどがあります。

Lesson 13
Chapter 5
シェルスクリプトの出力結果を保存してみよう
シェルスクリプトを実行し、その出力結果をテキストファイルなどに出力することが出来ます。コマンドは以下の通りです。
$ [コマンド(シェルスクリプト)] > [出力先のファイル名]
まずはシンプルな"Hello World!"を標準出力するだけのhello.sh
というシェルスクリプトを用意します。
#!/bin/bash
echo "Hello World!"
それでは上記スクリプトの標準出力をtest.txt
というテキストファイルに向けて実行してみます。
$ ./hello.sh > test.txt
text.txt
ファイルを開くとHello World!
という文字列が1行表示されます。
また、以下のように>
を2つ重ねることで、標準出力を受け取る度にファイルに結果を追記する事もできます。
$ ./hello.sh >> test.txt
こうすることで、上記コマンドを実行する度にtest.txt
ファイルに"Hello
World!"という文字列が1行ずつ追加されていきます。

Lesson 13
Chapter 6
制御構文を使って特殊な処理の流れを作ってみよう
基本的にシェルスクリプトは、上から下へ順番にコマンドが処理されて行きます。
そこで、このチャプターでは特定の条件によって処理の流れを制御するコマンドである「制御構文」について学習していきます。
ここではif(イフ)文
, while(ホワイル)文
, for(フォー)文
という3つの制御構文を紹介します。
if文
if文では特定の条件が成立した際に実行する処理を記述します。条件式に当てはまる場合を真(True)と呼び、当てはまらない場合を偽(False)と呼びます。 基本的な書き方は以下の通りです。
if
で始まりfi
で終わる。if
の右隣に条件式を記述する。- 条件式は[ ]で囲むこと。(条件式と括弧の間には半角スペースを入れる)
- 条件式が真の場合の処理はif文直下の
then
の下に記述する。 - 条件式が偽の場合の処理は
else
の下に記述する。
if [ 条件式 ];
then
処理1
else
処理2
fi
条件式では主に「数値の比較」と「文字列の比較」があります。それぞれの条件式の書き方は以下のものがあります。
数値の比較
条件式 | 説明 |
---|---|
数値1 -eq 数値2 | 数値1と数値2が等しければ真 |
数値1 -ne 数値2 | 数値1と数値2が等しくなければ真 |
数値1 -gt 数値2 | 数値1が数値2よりも大きければ真 |
数値1 -ge 数値2 | 数値1が数値2以上であれば真 |
数値1 -lt 数値2 | 数値1が数値2よりも小さければ真 |
数値1 -le 数値2 | 数値1が数値2以下であれば真 |
文字列の比較
条件式 | 説明 |
---|---|
文字列1 = 文字列2 | 文字列1と文字列2が等しければ真 |
文字列1 != 文字列2 | 文字列1と文字列2が等しくなければ真 |
-n 文字列 | 文字列の長さ(文字数)が1以上であれば真 |
-z 文字列 | 文字列の長さ(文字数)が0であれば真 |
それでは実際にif文を利用して、変数の値によって標準出力分を切り分けるシェルスクリプトを書いていきます。
#!/bin/bash
text="Hello"
if [ $text = "Hello" ];
then
echo "Hello World!"
else
echo "Bye"
fi
このスクリプトはtext
変数の値が"Hello"だった場合に
Hello World!
を出力し、それ以外の場合はBye
を出力する処理となっています。
ここではtext変数の初期値に"Hello"という文字列を代入しているため、実行結果は
Hello World!
が出力されることになります。
また、elif
を使うことで条件式を増やして処理の分岐を増やすことも出来ます。
#!/bin/bash
text="morning"
if [ $text = "Hello" ];
then
echo "Hello World!"
elif [ $text = "morning" ];
then
echo "Good morning!"
else
echo "Bye"
fi
これは先程のスクリプトにelif
による条件分岐を増やしたものになります。
text
変数の値が"morning"であった場合に
Good morning!
というテキストを出力する処理が追加されています。この時、elseの処理が実行される条件は
text
変数の値が"Hello"でも"morning"でも無い場合ということになります。
while文
while文は条件文が真である間、記述した処理を繰り返します。条件式はif文と同じように書くことが出来ます。
while [ 条件式 ]
do
処理
done
count
変数の値を処理1回ごとに数値として+1していき、count
の値が5未満でなくなった時にループ処理を終了するスクリプトを書いていきます。
#!/bin/bash
count=0
while [ $count -lt 5 ]
do
count=$((count + 1))
echo "Good morning!"
done
count
変数の初期値は0であるため、このwhile文の処理は5回行われるということになります。
また、$(( ))
はcount
変数を数値データとして扱うための記法になります。
for文
for文では、変数にデータリストの各要素が左から順番に代入され、処理が実行されます。データリストにある複数の値は半角スペース区切りで定義します。データリストから全ての値を取り出して処理されるとループが終了します。
for 変数名 in 変数に代入する値のリスト
do
処理
done
では、データリストに3つの文字列を定義して順に出力するスクリプトを書いていきます。
#!/bin/bash
for text in "nice" "great" "excellent"
do
echo $text
done
実際の実行結果は以下のようになります。
$ ./test.sh
nice
great
excellent
データリストに定義した各文字列が1行ずつ標準出力されていることが確認できました。

Lesson 13
Chapter 7
利用者からの入力を受け取る
シェルスクリプトを実行と同時にパラメータとして入力値を与えることは学びましたが実行中に適時、ユーザーからの入力を受け取ることも出来ます。
このチャプターでは、標準入力からの入力を受け付けるread(リード)
コマンドについて学習していきます。基本的なコマンドの書き方は以下の通りです。
read [変数名]
では実際に、キーボードから名前を入力し、ウェルカムメッセージを標準出力するスクリプトを書いていきます。
#!/bin/bash
read name
echo "$name さん、こんにちは"
上記スクリプトを実行すると、コンソールのカーソルが点滅し「入力待ち状態」となります。この状態で任意の文字列を入力し、エンターキーを押すと標準入力が完了します。
$ ./test.sh
太郎
太郎 さん、こんにちは
このように入力した値(名前)と" さん、こんにちは"という文字列を連結して出力されていることが確認できます。
select文
select文は、複数の選択肢を表示し、ユーザーからの選択を待ち受けることが出来ます。基本的な書き方は以下の通りです。
select 変数名 in 選択肢となるデータリスト
do
処理
done
まず最初に、先程のfor文を使用したスクリプトをselect文へ書き換えてみましょう。
#!/bin/bash
select text in "nice" "great" "excellent"
do
echo $text
done
変更箇所としては、for
の記述をselect
へ変更しました。これを実行してみます。
$ ./test.sh
1) nice
2) great
3) excellent
#?
すると、1, 2, 3という選択肢にデータリストとして渡した値が表示されている事が確認できます。さらに、#?
という表示があり入力待ち状態になっています。
試しに2
を入力すると、
$ ./test.sh
1) nice
2) great
3) excellent
#? 2
great
#?
選択肢2に該当するgreat
という文字列が出力され、次の入力待ち状態になっていることが確認できます。
処理の流れとしては、選択肢の番号を入力すると、その番号に対応した選択肢の値がtext
変数に格納されて処理が実行されるといった流れになります。
また、今の状態では永遠に処理のループを繰り返してしまいますがbreak
を利用することでループを終了することも出来ます。
#!/bin/bash
select text in "nice" "great" "excellent"
do
echo $text
break
done
こうすることで、選択肢の入力とその後の処理が行われたあとにbreak
が実行されてループを終了することが出来ます。

Lesson 13
Chapter 8
関数
関数とは、特定の処理をまとめたものであり、複数回使用することができるようにするためのものです。 一度関数として定義した処理は、その関数を呼び出すだけで関数に記述された処理を行うことが可能です。 シェルスクリプトでは、関数を以下のように定義します。
#!/bin/bash
function 関数名 () {
処理
}
例として"Hello World"を出力する処理を関数に定義し、それを呼び出すスクリプトを書いていきます。
#!/bin/bash
function sayHello () {
echo "Hello World!"
}
sayHello
このように関数名を記述するだけで関数を呼び出すことが出来ます。また、パラメータと同じように関数に対して引数を渡すことも出来ます。
#!/bin/bash
function sayHello () {
echo "$1 さん こんにちは!"
}
sayHello "太郎"
引数を渡す際は関数呼び出しの隣に半角スペースを開けて値を記述します。ここでは"太郎"という文字列を
sayHello
関数に渡しており、受け取った引数と" さん こんにちは!"を連結して出力しています。
複雑なシェルスクリプトを書いていく上で、何度も頻出する処理は関数としてまとめることで、読みやすいスクリプトになるというメリットがあります。
ここまでお疲れさまでした。 このレッスンでは主に「シェルスクリプトの概要」「シェルスクリプトの書き方」などについて学んできました。 シェルスクリプトを使いこなすことで、効率的で可読性の高いプログラムを記述することができ、ちょっとした業務の自動化や効率化を図ることが出来ます。
