シェルスクリプトの書き方入門 - Bash変数・条件分岐・ループ

シェルスクリプトの書き方入門 - Bash変数・条件分岐・ループ

シェルスクリプトは、Linuxシステムでの作業を自動化する強力なツールです。この基礎編では、Bashスクリプトの基本構文から条件分岐、ループ処理まで、実践的な例とともに学習します。

はじめてのシェルスクリプト

基本構造

#!/bin/bash
# これはコメントです

echo "Hello, Shell Script!"
echo "現在の日時: $(date)"
echo "ユーザー名: $USER"

スクリプトの作成と実行

ステップ1: ファイル作成

$ nano hello.sh

上記のコードを入力して保存する。

ステップ2: 実行権限の付与

$ chmod +x hello.sh

ステップ3: スクリプト実行

$ ./hello.sh
Hello, Shell Script!
現在の日時: 月 1月 11 14:30:00 JST 2025
ユーザー名: user

シェバン(Shebang)について

#!/bin/bashシェバン(shebang)と呼ばれ、このファイルを実行するインタープリターを指定する。

  • #!/bin/bash — Bashを使用
  • #!/bin/sh — POSIXシェルを使用
  • #!/usr/bin/env bash — 環境から自動検出

変数と入力

変数の基本

#!/bin/bash

# 変数の定義(=の前後にスペースを入れない)
name="Linux User"
age=25
today=$(date +%Y-%m-%d)

# 変数の使用
echo "名前: $name"
echo "年齢: ${age}歳"
echo "今日の日付: $today"

計算の例

#!/bin/bash

num1=10
num2=3

sum=$((num1 + num2))
diff=$((num1 - num2))
product=$((num1 * num2))
quotient=$((num1 / num2))

echo "足し算: $num1 + $num2 = $sum"
echo "引き算: $num1 - $num2 = $diff"
echo "掛け算: $num1 × $num2 = $product"
echo "割り算: $num1 ÷ $num2 = $quotient"

特殊変数

変数 説明
$0 スクリプト名 ./script.sh
$1, $2, ... コマンドライン引数 第1引数、第2引数
$# 引数の個数 3個の引数なら3
$@ すべての引数 "arg1" "arg2" "arg3"
$? 直前のコマンドの終了ステータス 成功なら0、失敗なら非0
$$ 現在のプロセスID 12345
$USER 現在のユーザー名 user
$HOME ホームディレクトリ /home/user
$PWD 現在のディレクトリ /home/user/scripts

ユーザー入力

基本的な入力

#!/bin/bash

echo "あなたの名前を入力してください:"
read name
echo "こんにちは、${name}さん!"

プロンプト付き入力

#!/bin/bash

read -p "年齢を入力してください: " age
read -s -p "パスワードを入力してください: " password
echo
echo "年齢: $age"
echo "パスワードは非表示で入力されました"

複数の値を一度に入力

#!/bin/bash

echo "名前と年齢をスペース区切りで入力:"
read name age
echo "名前: $name, 年齢: $age"

条件分岐

if文

基本的なif文

#!/bin/bash

read -p "数値を入力してください: " num

if [ "$num" -gt 0 ]; then
    echo "$num は正の数です"
elif [ "$num" -lt 0 ]; then
    echo "$num は負の数です"
else
    echo "$num はゼロです"
fi

ファイル存在チェック

#!/bin/bash

filename="test.txt"

if [ -f "$filename" ]; then
    echo "$filename は存在します"
    echo "ファイルサイズ: $(wc -c < "$filename") bytes"
else
    echo "$filename は存在しません"
    echo "ファイルを作成します..."
    touch "$filename"
fi

条件演算子

数値比較

演算子 意味
-eq 等しい [ $a -eq $b ]
-ne 等しくない [ $a -ne $b ]
-gt より大きい [ $a -gt $b ]
-ge 以上 [ $a -ge $b ]
-lt より小さい [ $a -lt $b ]
-le 以下 [ $a -le $b ]

文字列比較

演算子 意味
= 等しい [ "$a" = "$b" ]
!= 等しくない [ "$a" != "$b" ]
-z 空文字列 [ -z "$str" ]
-n 空でない [ -n "$str" ]

ファイルテスト

演算子 意味
-f 通常ファイル [ -f file.txt ]
-d ディレクトリ [ -d /home ]
-e 存在する [ -e path ]
-r 読み取り可能 [ -r file ]
-w 書き込み可能 [ -w file ]
-x 実行可能 [ -x script ]

case文

#!/bin/bash

echo "操作を選択してください:"
echo "1) ファイル一覧表示"
echo "2) 現在時刻表示"
echo "3) システム情報表示"
echo "4) 終了"

read -p "選択 (1-4): " choice

case $choice in
    1)
        echo "=== ファイル一覧 ==="
        ls -la
        ;;
    2)
        echo "=== 現在時刻 ==="
        date
        ;;
    3)
        echo "=== システム情報 ==="
        uname -a
        ;;
    4)
        echo "終了します。"
        exit 0
        ;;
    *)
        echo "無効な選択です。"
        ;;
esac

ループ処理

forループ

基本的なforループ

#!/bin/bash

# 数値の範囲
for i in {1..5}
do
    echo "カウント: $i"
done

echo "---"

# ファイル処理
for file in *.txt
do
    echo "処理中: $file"
    wc -l "$file"
done

配列を使ったループ

#!/bin/bash

fruits=("apple" "banana" "orange" "grape")

echo "果物リスト:"
for fruit in "${fruits[@]}"
do
    echo "- $fruit"
done

C言語風forループ

#!/bin/bash

echo "九九表の一部:"
for ((i=1; i<=5; i++))
do
    for ((j=1; j<=5; j++))
    do
        result=$((i * j))
        printf "%2d " $result
    done
    echo
done

whileループ

基本的なwhileループ

#!/bin/bash

count=1
while [ $count -le 5 ]
do
    echo "ループ $count 回目"
    count=$((count + 1))
done

ファイル読み込み

#!/bin/bash

filename="data.txt"

if [ -f "$filename" ]; then
    while IFS= read -r line
    do
        echo "読み込み: $line"
    done < "$filename"
else
    echo "ファイル $filename が見つかりません"
fi

untilループ

#!/bin/bash

count=1
until [ $count -gt 5 ]
do
    echo "カウント: $count"
    count=$((count + 1))
done

ループ制御

  • break — ループを抜ける
  • continue — 次の反復へ
#!/bin/bash

for i in {1..10}
do
    if [ $i -eq 3 ]; then
        echo "3はスキップ"
        continue
    fi

    if [ $i -eq 8 ]; then
        echo "8で終了"
        break
    fi

    echo "数値: $i"
done

よくある間違いと落とし穴

間違い1: 変数定義時のスペース

NG(エラーになる)

name = "太郎"     # = の前後にスペース
age= 25          # = の後にスペース
city ="東京"     # = の前にスペース

「command not found」エラーになる。

OK(正しい書き方)

name="太郎"      # = の前後にスペースなし
age=25
city="東京"

変数の代入では = の前後にスペースを入れない。

間違い2: 変数参照時の{}忘れ

NG(予期しない結果)

filename="test"
echo "$filenameback.txt"    # 空になる
echo "$filename_backup"     # 空になる

OK(正しい書き方)

filename="test"
echo "${filename}back.txt"   # testback.txt
echo "${filename}_backup"    # test_backup

{} で変数名の範囲を明確にする。

間違い3: if文の条件式でのスペース不足

NG(構文エラー)

if [$num -gt 5]; then       # [の後ろにスペースなし
if [ $num -gt 5]; then      # ]の前にスペースなし

OK(正しい書き方)

if [ $num -gt 5 ]; then     # [ ] の内側にスペース必須
if [[ $num -gt 5 ]]; then   # [[ ]] を使う場合も同様
if (( num > 5 )); then      # 算術式の場合

間違い4: 文字列比較での引用符忘れ

NG(危険な例)

if [ $name = John Doe ]; then    # スペースが含まれると問題
if [ $empty_var = "" ]; then     # 空の場合エラー

OK(安全な書き方)

if [ "$name" = "John Doe" ]; then    # 両辺を引用符で囲む
if [ "$empty_var" = "" ]; then       # 空でもエラーにならない
if [ -z "$var" ]; then               # 空文字チェックの専用オプション

間違い5: コマンド置換での古い記法

NG(非推奨)

date=`date`                 # バッククォート
result=`cat `which ls``     # ネストでエラー

OK(現代的な記法)

date=$(date)                # $() を使用
result=$(cat $(which ls))   # ネストが容易

間違い6: 算術演算での間違い

NG(計算されない)

result = $num1 + $num2      # "result" コマンドとして解釈され command not found
sum="$a + $b"               # 計算されない

OK(正しい計算方法)

result=$((num1 + num2))     # 算術展開
let "result = num1 + num2"  # let コマンド使用

間違いを防ぐための基本ルール

記述の基本

  • 変数代入時: = の前後にスペースを入れない
  • 変数使用時: 常に引用符で囲む "$var"
  • 複雑な変数: {} で囲む "${var}"

条件文の基本

  • [ ] の使用: 内側に必ずスペースを入れる
  • 文字列比較: 両辺を引用符で囲む
  • 数値比較: -eq, -gt, -lt などを使用

デバッグとトラブルシューティング

#!/bin/bash

# デバッグモードを有効にする
set -x              # コマンドの実行を表示
set -e              # エラー時に停止
set -u              # 未定義変数でエラー

# 変数の内容を確認
echo "DEBUG: var = [$var]"

# ファイルの存在確認
if [ ! -f "$filename" ]; then
    echo "ERROR: ファイル $filename が見つかりません" >&2
    exit 1
fi

よくあるエラーメッセージと対処法

  • 「command not found」: 変数代入時の不要なスペース、実行権限の不足 → chmod +x script.sh
  • 「syntax error」: if文の [ ] 内のスペース不足、引用符の対応ミス、then/fi/done の記述忘れ
  • 「Permission denied」: 実行権限なし → chmod +x script.sh

次に読む