12-LPIC「level1」

LPIC|level 1【シェルスクリプト】

目標

  • シェルスクリプトについて理解する

シェルスクリプト(Shell Script)

シェルスクリプト(Shell Script)は、LinuxやUnix系のシェル(Bash、Zshなど)で実行される一連のコマンドを記述したテキストファイルです。シェルスクリプトは、繰り返し行う作業を自動化するために非常に便利で、システム管理やソフトウェアのインストール、ファイル操作などを簡単に行えるツールです。

シェルスクリプトの書き方

シェルスクリプトを作成する場合、基本的な構文を理解していることと、可読性の高い記述方法について理解していることが求められます。ここでは、段階を追って少しずつ学習していきます。

基本的な構文

スクリプトで最初に書くこと

シバン(shebang)

シェルスクリプトは通常、スクリプトの最初に「シバン(shebang)」と呼ばれる一行を記述して、使用するシェルを指定します。Bashを使用する場合、以下のように書きます。

#!/bin/bash

コメントの入力方法

コメント

コメントは#で始まります。スクリプト内での説明やメモを記述するために使用します。

# これはコメントです
基本的なシェルスクリプト

このスクリプトは、ユーザーから名前を入力してもらい、その名前を使って挨拶を行うプログラムです。(greet.shという名前で保存します。)

#!/bin/bash

# ユーザーに名前を入力させる
echo "名前を入力してください:"
read name

# 挨拶する
echo "こんにちは、$name さん!"

【スクリプトの説明】

  1. #!/bin/bash:Bashシェルを使ってスクリプトを実行することを指定します。
  2. echo “名前を入力してください:”:echoコマンドでユーザーに入力を促すメッセージを表示します。
  3. read name:readコマンドを使用して、ユーザーから入力を受け取り、それをnameという変数に格納します。
  4. 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

【スクリプトの説明】

  1. read age:年齢をageという変数に格納します。
  2. if [ $age -ge 18 ]:年齢が18歳以上かどうかを判定します。-geは「greater than or equal to」の意味です。
  3. then:条件が真の場合に実行する処理を記述します。
  4. else:条件が偽の場合に実行する処理を記述します。
  5. fi:if文の終了を示します。

実行方法はスクリプトを保存して実行するだけです。

-ge は整数比較用となります。利用している変数の値が数値である必要があります。本来であれば、入力が数値かどうかのバリデーションが必要となります。

ループ処理

シェルスクリプトにおける繰り返し処理(ループ)は、ある処理を繰り返し実行したいときに使用します。繰り返し処理は、反復的なタスクを自動化するのに非常に便利です。シェルスクリプトには、主に以下の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 ループで範囲を指定する

for ループは、数値の範囲を使って繰り返し処理を行うこともできます。{}(波括弧)を使って範囲を指定します。

#!/bin/bash

for i in {1..5}
do
    echo "現在の数字は $i です"
done

このスクリプトは、、1 から 5 までの範囲を指定して繰り返し処理を実行します。

波括弧の範囲展開 {1..5} は、Bash 以外の環境では実行できないことがあります。

例: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まで増やしながら繰り返し処理を行います。

((i++)) は i を1増やす記法です。i++ はインクリメント演算子です。

例:while ループでユーザー入力を繰り返す

ユーザーに入力を促し、その入力が「exit」になるまで繰り返し受け付ける例です。

#!/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 ループでカウントアップ

while ループと似た動作をしますが、条件が偽の場合に繰り返し処理を実行します。

#!/bin/bash

i=1

until [ $i -gt 5 ]
do
    echo "現在の数字は $i です"
    ((i++))  # i をインクリメント
done

このスクリプトは、i が5を超えるまで繰り返し処理を行います。

for / while / until の使い分け
for ループ: 繰り返す回数やリストが明確な場合に使用します。特にリストや範囲、ステップを使った繰り返しに便利です。

while ループ: 条件が真である間繰り返し処理を行いたい場合に使用します。ユーザー入力や動的な条件に適しています。

until ループ: 条件が偽の間繰り返し処理を行いたい場合に使用します。while ループの逆の動きです。

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 “太郎”:関数を呼び出し、引数として太郎を渡します。

可読性の高い記述方法

シェルスクリプトを書く際には、コードが効率的で読みやすく、エラーが起こりにくいように工夫することが重要です。以下は、シェルスクリプトを書く際のコツです。

  1. スクリプトの目的を明確にする:まず、スクリプトを書く目的を明確にします。自動化したいタスクや実現したい処理を具体的に決めることで、無駄なコードを書かず、必要な機能に集中できます。
  2. エラー処理を忘れずに:シェルスクリプトは、予期しないエラーやユーザー入力ミスなどが発生することがあります。これに対処するために、エラーチェックやエラー処理をしっかり行います。

エラー処理の方法

コマンド実行後にエラーが発生した場合に終了するように設定する(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"

今回は以上になります。

「Linux」おすすめ書籍6選【初心者・脱初心者用】| 現役エンジニア&プログラミングスクール講師「Linux」初心者の方がLinuxの操作や仕組みを理解するためのお勧めの書籍について取り上げています。また中級者として更に進んだ学習ができる書籍についても1冊取り上げています。ページの下部には「おすすめのITスクール情報」「おすすめ求人サイト」について情報を掲載中。...

ブックマークのすすめ

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

「お気に入り」の登録・削除方法【Google Chrome / Microsoft Edge】「お気に入り」の登録・削除方法【Google Chrome / Microsoft Edge】について解説している記事です。削除方法も掲載しています。...
【パソコン選び】失敗しないための重要ポイント | 現役エンジニア&プログラミングスクール講師【パソコン選び】失敗しないための重要ポイントについての記事です。パソコンのタイプと購入時に検討すべき点・家電量販店で見かけるCPUの見方・購入者が必要とするメモリ容量・HDDとSSDについて・ディスプレイの種類・バッテリーの持ち時間や保証・Officeソフト・ウィルス対策ソフトについて書いています。...

RELATED POST