目標
- シェルスクリプトについて理解する
シェルスクリプト(Shell Script)
シェルスクリプト(Shell Script)は、LinuxやUnix系のシェル(Bash、Zshなど)で実行される一連のコマンドを記述したテキストファイルです。シェルスクリプトは、繰り返し行う作業を自動化するために非常に便利で、システム管理やソフトウェアのインストール、ファイル操作などを簡単に行えるツールです。
シェルスクリプトの書き方
シェルスクリプトを作成する場合、基本的な構文を理解していることと、可読性の高い記述方法について理解していることが求められます。ここでは、段階を追って少しずつ学習していきます。
基本的な構文
スクリプトで最初に書くこと
シバン(shebang)
シェルスクリプトは通常、スクリプトの最初に「シバン(shebang)」と呼ばれる一行を記述して、使用するシェルを指定します。Bashを使用する場合、以下のように書きます。
#!/bin/bash
コメントの入力方法
コメント
コメントは#で始まります。スクリプト内での説明やメモを記述するために使用します。
# これはコメントです
基本的なシェルスクリプト
このスクリプトは、ユーザーから名前を入力してもらい、その名前を使って挨拶を行うプログラムです。(greet.shという名前で保存します。)
#!/bin/bash
# ユーザーに名前を入力させる
echo "名前を入力してください:"
read name
# 挨拶する
echo "こんにちは、$name さん!"
【スクリプトの説明】
- #!/bin/bash:Bashシェルを使ってスクリプトを実行することを指定します。
- echo “名前を入力してください:”:echoコマンドでユーザーに入力を促すメッセージを表示します。
- read name:readコマンドを使用して、ユーザーから入力を受け取り、それをnameという変数に格納します。
- echo “こんにちは、$name さん!”:echoで挨拶を表示します。$nameは先ほど入力された名前を指します。
【実行方法】
スクリプトに実行権限を与えます。
chmod +x greet.sh
スクリプトを実行します。
./greet.sh
条件分岐(if文)
シェルスクリプトでは、条件分岐を使って異なる処理を行うことができます。
基本構文(if文)
if 条件
then
# 条件が真の場合に実行される処理
fi
基本構文(if-else文)
if 条件
then
# 条件が真の場合に実行される処理
else
# 条件が偽の場合に実行される処理
fi
次の例では、ユーザーに年齢を入力してもらい、成人か未成年かを判定します。
#!/bin/bash
# ユーザーに年齢を入力してもらう
echo "年齢を入力してください:"
read age
# 年齢に基づいて処理を分ける
if [ $age -ge 18 ]; then
echo "あなたは成人です。"
else
echo "あなたは未成年です。"
fi
【スクリプトの説明】
- read age:年齢をageという変数に格納します。
- if [ $age -ge 18 ]:年齢が18歳以上かどうかを判定します。-geは「greater than or equal to」の意味です。
- then:条件が真の場合に実行する処理を記述します。
- else:条件が偽の場合に実行する処理を記述します。
- fi:if文の終了を示します。
実行方法はスクリプトを保存して実行するだけです。
ループ処理
シェルスクリプトにおける繰り返し処理(ループ)は、ある処理を繰り返し実行したいときに使用します。繰り返し処理は、反復的なタスクを自動化するのに非常に便利です。シェルスクリプトには、主に以下の3つの繰り返し構文があります。
- for ループ
- while ループ
- until ループ
for ループ
for ループは、リスト内の各要素に対して一度ずつ処理を行いたい場合に使用します。
基本構文
for 変数 in リスト
do
# 繰り返す処理
done
例:数値のリストを繰り返す
#!/bin/bash
for i in 1 2 3 4 5
do
echo "現在の数字は $i です"
done
このスクリプトは、1から5までの数値を順番に表示します。
例:for ループで範囲を指定する
#!/bin/bash
for i in {1..5}
do
echo "現在の数字は $i です"
done
このスクリプトは、、1 から 5 までの範囲を指定して繰り返し処理を実行します。
例:for ループでステップを指定する
#!/bin/bash
for i in {1..10..2}
do
echo "現在の数字は $i です"
done
このスクリプトは、1 から 10 までの数値を2ずつ増加させて繰り返し処理を実行します(1, 3, 5, 7, 9)。
while ループ
while ループは、指定した条件が真である限り繰り返し処理を行います。条件が真であれば処理を繰り返し、偽になると停止します。
基本構文
while 条件
do
# 条件が真の間、繰り返す処理
done
例:while ループでカウントアップ
#!/bin/bash
i=1
while [ $i -le 5 ]
do
echo "現在の数字は $i です"
((i++)) # i をインクリメント
done
このスクリプトは、変数 i を1から5まで増やしながら繰り返し処理を行います。
例:while ループでユーザー入力を繰り返す
#!/bin/bash
while true
do
echo "終了するには 'exit' を入力してください。"
read input
if [ "$input" = "exit" ]; then
echo "終了します。"
break
else
echo "入力された内容: $input"
fi
done
このスクリプトは、exit という文字列が入力されるまで繰り返しユーザー入力を受け付けます。
until ループ
until ループは、指定した条件が偽である限り繰り返し処理を行います。条件が真になると、ループは終了します。
until 条件
do
# 条件が偽の間、繰り返す処理
done
例:until ループでカウントアップ
#!/bin/bash
i=1
until [ $i -gt 5 ]
do
echo "現在の数字は $i です"
((i++)) # i をインクリメント
done
このスクリプトは、i が5を超えるまで繰り返し処理を行います。
break と continue
break文とcontinue文には次の違いがあります。
- break: ループを途中で終了させる。
- continue: ループの現在の繰り返しをスキップして、次の繰り返しに進む。
例:break を使う … このスクリプトは、i が5に達するとループを終了します。
#!/bin/bash
for i in {1..10}
do
if [ $i -eq 5 ]; then
echo "5に達したのでループを終了します。"
break
fi
echo "現在の数字は $i です"
done
例:continue を使う … このスクリプトは、i が5のときにその繰り返しをスキップし、次の繰り返しに進みます。
#!/bin/bash
for i in {1..10}
do
if [ $i -eq 5 ]; then
echo "5はスキップします。"
continue
fi
echo "現在の数字は $i です"
done
無限ループ
無限ループを作成する場合もあります。例えば、サーバーの監視スクリプトや継続的な入力受付処理などで使います。
例:無限ループ(while) … このスクリプトは無限に繰り返し実行され、ユーザーが手動で中断(CTRL+C)するまで動作します。
#!/bin/bash
while true
do
echo "無限ループ中... CTRL+C で終了"
sleep 1 # 1秒待機
done
引数の取り扱い
シェルスクリプトでは、コマンドライン引数を受け取ることもできます。例えば、ファイル名を引数として渡し、その内容を表示するスクリプトを作成します。
例:コマンドライン引数を受け取るスクリプト
#!/bin/bash
# 引数を表示
echo "指定されたファイル名は: $1"
# ファイルの内容を表示
cat $1
【スクリプトの説明】
$1:コマンドライン引数の1番目を受け取ります。例えば、スクリプトを実行する際にファイル名を引数として渡すと、そのファイル名が表示されます。
cat $1:引数として渡されたファイルの内容を表示します。
実行方法は、スクリプトを保存し、実行権限を与えた後に、ファイル名を引数として渡して実行します。
./read_file.sh sample.txt
関数の定義
シェルスクリプトでは、関数を定義して再利用可能なコードを作成することもできます。
例:関数を使ったスクリプト
#!/bin/bash
# 関数定義
greet_user() {
echo "こんにちは、$1さん!"
}
# 関数呼び出し
greet_user "太郎"
【スクリプトの説明】
greet_user():greet_userという関数を定義します。関数は引数を受け取ることができます(ここでは名前)。
greet_user “太郎”:関数を呼び出し、引数として太郎を渡します。
可読性の高い記述方法
シェルスクリプトを書く際には、コードが効率的で読みやすく、エラーが起こりにくいように工夫することが重要です。以下は、シェルスクリプトを書く際のコツです。
- スクリプトの目的を明確にする:まず、スクリプトを書く目的を明確にします。自動化したいタスクや実現したい処理を具体的に決めることで、無駄なコードを書かず、必要な機能に集中できます。
- エラー処理を忘れずに:シェルスクリプトは、予期しないエラーやユーザー入力ミスなどが発生することがあります。これに対処するために、エラーチェックやエラー処理をしっかり行います。
エラー処理の方法
コマンド実行後にエラーが発生した場合に終了するように設定する(set -e)
# スクリプトがエラーを検出したら停止する
set -e
特定のコマンドが失敗した場合にエラーメッセージを表示して終了する
if ! command; then
echo "エラーが発生しました"
exit 1
fi
||(OR)を使ってエラーを処理
command || { echo "コマンド失敗"; exit 1; }
入力のバリデーション
バリデーションとは、ユーザーからの入力に対して、入力値が期待される形式かどうかを確認する処理をいいます。値の入力をユーザーに行わせる場合は、バリデーションを行うことが重要です。
例:数値の入力確認
#!/bin/bash
echo "年齢を入力してください:"
read age
# 数値かどうかをチェック
if ! [[ "$age" =~ ^[0-9]+$ ]]; then
echo "エラー: 数値を入力してください"
exit 1
fi
echo "入力された年齢は $age 歳です"
変数の引用を忘れない
シェルスクリプトでは、変数を使用する際に引用(”)を忘れないように注意が必要です。引用がないと、変数の中にスペースが含まれている場合などに予期しない動作をすることがあります。引用を使うことで、変数内の空白や特殊文字が適切に処理されます。
# 引用しない例
echo $name
# 引用した例
echo "$name"
シェルのオプションを活用する
シェルスクリプトを書く際に便利なシェルオプションがあります。以下はよく使われるオプションです。
- set -e:コマンドがエラーを返した場合にスクリプトを終了させる
- set -u:未定義の変数が使われた場合にエラーを発生させる
- set -o pipefail:パイプライン内のコマンドが失敗した場合にエラーを返す
#!/bin/bash
set -e
set -u
set -o pipefail
# スクリプト内でエラーが発生した場合にすぐに停止する
関数を活用する
繰り返し使う処理や、処理が長くなる場合は関数を定義してコードを整理します。関数を使うことで、コードの再利用性が向上し、スクリプトが読みやすくなります。
関数の例
#!/bin/bash
# 関数定義
greet_user() {
echo "こんにちは、$1さん!"
}
# 関数呼び出し
greet_user "太郎"
ログを活用する
スクリプトの動作状況を把握するために、ログファイルにメッセージを書き込むのも良く行われる手法です。これにより、スクリプトの実行履歴やエラーの原因を追跡できます。
ログファイルへの出力例
#!/bin/bash
LOGFILE="script.log"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOGFILE
}
log_message "スクリプトが開始されました"
# 処理の例
echo "処理中..."
log_message "スクリプトが終了しました"
スクリプトの可読性を高める
プログラムを書く際は、スクリプトが他の人にも理解しやすいように、可読性を高める工夫が重要です。次のような項目に注意して記述すると可読性が上がります。
- インデント:関数や条件文、ループ内のコードはインデントを使って整理します。
- コメント:コードの意図を説明するコメントを適切に挿入します。
- 変数名をわかりやすくする:変数名はその役割がわかるように命名します。
可読性の高いコード例
#!/bin/bash
# ファイルをバックアップする関数
backup_file() {
local src_file=$1
local dest_file=$2
# ソースファイルが存在するか確認
if [[ ! -f "$src_file" ]]; then
echo "エラー: ソースファイルが見つかりません"
return 1
fi
# バックアップを作成
cp "$src_file" "$dest_file"
echo "バックアップが完了しました: $dest_file"
}
# 実行例
backup_file "/path/to/source.txt" "/path/to/backup.txt"
デバッグのためにトレースを使う
スクリプトの動作を確認するために、デバッグモードを有効にして実行の流れを追いやすくすることができます。
#!/bin/bash
set -x # トレースを有効にする
echo "スクリプトが開始されました"
# 実行されるコマンドとその引数が表示される
set +x # トレースを無効にする
不要なファイルやデータの削除
スクリプト内で生成した一時ファイルや不要なデータは、最後に削除してクリーンに保つよにこころがけます。
# 一時ファイルを作成
tempfile=$(mktemp)
# 処理を行う
# 最後に一時ファイルを削除
rm -f "$tempfile"
今回は以上になります。

ブックマークのすすめ
「ほわほわぶろぐ」を常に検索するのが面倒だという方はブックマークをお勧めします。ブックマークの設定は別記事にて掲載しています。

