シェルスクリプト基礎:自動化の第一歩

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

目次

  1. はじめてのシェルスクリプト
  2. 変数と入力
  3. 条件分岐
  4. ループ処理

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

基本的な構造

最初のスクリプト

#!/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 - 環境から自動検出

2. 変数と入力

変数の基本

変数の定義と使用

#!/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"

3. 条件分岐

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

4. ループ処理

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: 変数定義時のスペース

❌ エラーになる例

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

「command not found」エラーになります。

✅ 正しい書き方

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

変数の代入では = の前後にスペースを入れてはいけません。

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

❌ 予期しない結果

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

変数名の境界が不明確で正しく展開されません。

✅ 正しい書き方

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

{}を使って変数名の範囲を明確にします。

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

❌ エラーになる例

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

構文エラーになります。

✅ 正しい書き方

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

[ ] の内側には必ずスペースを入れます。

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

❌ 危険な例

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

変数が空だったりスペースを含むとエラーになります。

✅ 安全な書き方

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

変数は常に引用符で囲むのが安全です。

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

❌ 古い記法(非推奨)

date=`date`                 # バッククォート
files=`ls *.txt`            # ネストが困難
result=`cat `which ls``     # ネストでエラー

バッククォートはネストが困難で読みにくいです。

✅ 現代的な記法(推奨)

date=$(date)                # $() を使用
files=$(ls *.txt)           # 読みやすい
result=$(cat $(which ls))   # ネストが容易

$() 記法を使うと読みやすく、ネストも簡単です。

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

❌ エラーになる例

result = $num1 + $num2      # シェルでは文字列として扱われる
sum="$a + $b"               # 計算されない

シェルはデフォルトで全てを文字列として扱います。

✅ 正しい計算方法

result=$((num1 + num2))     # 算術展開
sum=$(($a + $b))            # 括弧内で計算
let "result = num1 + num2"  # let コマンド使用

$(()) または let を使って算術演算を行います。

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

📝 記述の基本

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

🔍 条件文の基本

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

⚙️ 実行とテスト

  • 段階的開発: 少しずつ機能を追加してテスト
  • エラー確認: set -e でエラー時に停止
  • デバッグ: set -x でコマンド実行を表示

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

基本のデバッグ技法

#!/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
  • ファイルへの書き込み権限なし
  • ディレクトリの実行権限なし

🚀 次のステップ

シェルスクリプトの基本構文をマスターしたら、実践編でより高度な技術を学びましょう:

📋 実践編で学ぶ内容

  • 関数 - コードの再利用と構造化
  • 配列 - 複数データの効率的な処理
  • ファイル操作 - 読み書きと高度なファイル処理
  • エラー処理 - 堅牢なスクリプト作成
  • 実践例 - 実際の業務で使えるスクリプト
実践編に進む →

📋 シェルスクリプトシリーズ全体

  1. 基礎編(この記事) - 変数、条件分岐、ループ、関数
  2. 実践編 - 実務シナリオ、エラーハンドリング、最適化
📢 アフィリエイトリンクについて

当サイトは、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイトプログラムである「Amazonアソシエイト・プログラム」の参加者です。商品価格に影響はありません。

🎉 実践でシェルスクリプトをマスターしよう

書籍で知識を習得したら、Penguin Gym Linuxの実践課題で手を動かして学習を定着させましょう。変数、条件分岐、ループを実際に使うことで、確実にスキルアップできます。