Shell Script とは?初心者が最短で理解する基本構文・実行モデル・活用領域
Shell Script と聞いて、「難しそう」「黒い画面で何をしているのかわからない」と感じたことはありませんか?
実は、Shell Script は開発現場で最も頻繁に使われる基本技術の 1 つです。サーバー管理からアプリケーション開発まで、幅広い場面で活躍します。本記事では、Shell Script の基本から実行の仕組み、そして実務で役立つ活用例まで、初心者の方でも最短で理解できるように丁寧に解説していきますね。
この記事を読み終える頃には、Shell Script の本質を理解し、自分で簡単なスクリプトを書けるようになっているはずです。
背景
Shell Script が生まれた理由
コンピュータを操作する方法は大きく分けて 2 つあります。1 つはマウスでクリックする GUI(Graphical User Interface)、もう 1 つはキーボードでコマンドを入力する CLI(Command Line Interface)ですね。
Shell Script は、この CLI での操作を自動化するために生まれました。
mermaidflowchart TB
user["ユーザー"] -->|コマンド入力| shell["Shell<br/>コマンド解釈プログラム"]
shell -->|システムコール| kernel["カーネル<br/>OS の中核"]
kernel -->|制御| hardware["ハードウェア<br/>CPU/メモリ/ディスク"]
hardware -->|結果| kernel
kernel -->|応答| shell
shell -->|出力表示| user
図で理解できる要点:
- Shell はユーザーとカーネルの橋渡し役として動作します
- コマンドを解釈してシステムに伝え、結果をユーザーに返します
- この一連の流れを自動化したものが Shell Script です
Shell の種類と歴史
Unix/Linux の世界では、いくつかの Shell が開発されてきました。
| # | Shell 名 | 特徴 | 主な用途 |
|---|---|---|---|
| 1 | sh | 最も基本的な Shell | 互換性重視のスクリプト |
| 2 | bash | sh の拡張版で最も普及 | Linux の標準 Shell |
| 3 | zsh | bash より高機能 | macOS Catalina 以降の標準 |
| 4 | fish | モダンで使いやすい | 対話的な操作向け |
現在では bash(Bourne Again Shell)が最も広く使われており、本記事でも bash を基準に解説しますね。
Shell Script の役割
Shell Script は、繰り返し実行するコマンドをまとめて自動化するためのツールです。
例えば、毎日同じ手順でバックアップを取る作業があったとします。手動で実行すると以下のようになります。
bashcd /home/user/data
tar -czf backup.tar.gz ./*
mv backup.tar.gz /backup/$(date +%Y%m%d)_backup.tar.gz
echo "バックアップ完了"
これらのコマンドを 1 つのファイルにまとめて保存すれば、1 回の実行で全ての作業が完了するわけです。これが Shell Script の基本的な考え方になります。
課題
手動操作の限界
開発やサーバー運用では、同じコマンドを何度も実行する場面が頻繁にありますね。
手動で実行する場合、以下のような課題が発生します。
| # | 課題 | 具体例 | 影響 |
|---|---|---|---|
| 1 | 入力ミス | コマンドのタイプミス | 予期しないエラーや削除 |
| 2 | 手順の抜け | 途中の工程を忘れる | 不完全な処理結果 |
| 3 | 時間のロス | 毎回同じ操作を繰り返す | 開発時間の浪費 |
| 4 | 属人化 | 作業者しか手順がわからない | チーム開発の妨げ |
特に深夜のデプロイ作業や、複数のサーバーに同じ設定を適用する場合、人間の注意力には限界があります。
複雑な処理の管理
システムが大きくなるにつれて、実行する処理も複雑になっていきます。
mermaidflowchart TB
start["デプロイ開始"] --> git["Git から最新コードを取得"]
git --> install["依存パッケージをインストール"]
install --> build["アプリケーションをビルド"]
build --> test["テストを実行"]
test --> check{テスト結果}
check -->|成功| deploy["本番環境にデプロイ"]
check -->|失敗| rollback["ロールバック処理"]
deploy --> notify["Slack に通知"]
rollback --> notify
notify --> done["完了"]
図で理解できる要点:
- デプロイには複数の工程があり、条件分岐も含まれます
- テスト失敗時の処理など、エラーハンドリングも必要です
- これらを手動で管理するのは非常に困難になります
チーム開発での共有
複数人で開発する場合、作業手順を共有する必要があります。
口頭やドキュメントでの共有には以下の問題がありますね。
- ドキュメントが更新されず、古い情報のままになる
- 人によって解釈が異なり、実行結果にばらつきが出る
- 新メンバーへの教育コストが高い
Shell Script として手順をコード化すれば、実行可能なドキュメントとして機能します。これにより、誰でも同じ結果を得られるようになるのです。
解決策
Shell Script による自動化
Shell Script を使えば、上記の課題を全て解決できます。
コマンドの組み合わせをファイル化することで、以下のメリットが得られますね。
| # | メリット | 説明 |
|---|---|---|
| 1 | 再現性 | 毎回同じ手順で実行される |
| 2 | 効率化 | 1 コマンドで複雑な処理を実行 |
| 3 | 共有可能 | Git で管理してチームで共有 |
| 4 | ドキュメント代わり | スクリプト自体が手順書になる |
基本的なスクリプトの構造
Shell Script は非常にシンプルな構造をしています。最小限のスクリプトを見てみましょう。
bash#!/bin/bash
この 1 行目は シバン(Shebang) と呼ばれ、どの Shell でスクリプトを実行するかを指定します。#!/bin/bash は「bash で実行してください」という意味ですね。
次に、実際にコマンドを記述していきます。
bash# 変数の定義
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)
# で始まる行はコメントです。変数は 変数名=値 の形式で定義します。$() の中のコマンドは実行結果が代入されますね。
bash# ディレクトリの移動
cd /home/user/data
# ファイルの圧縮
tar -czf backup.tar.gz ./*
コマンドをそのまま記述するだけで、順番に実行されます。
bash# バックアップファイルの移動
mv backup.tar.gz "${BACKUP_DIR}/${DATE}_backup.tar.gz"
# 完了メッセージの表示
echo "バックアップが完了しました: ${DATE}"
変数を使う場合は ${変数名} の形式で参照します。これで基本的なスクリプトの完成です。
実行モデルの理解
Shell Script の実行の流れを理解することが重要です。
mermaidflowchart LR
script["スクリプトファイル<br/>backup.sh"] -->|読み込み| shell["Shell プロセス"]
shell -->|1行ずつ解釈| cmd1["コマンド実行"]
cmd1 -->|次の行| cmd2["コマンド実行"]
cmd2 -->|次の行| cmd3["コマンド実行"]
cmd3 -->|終了| result["実行完了"]
図で理解できる要点:
- スクリプトは上から順番に 1 行ずつ実行されます
- 各コマンドは前のコマンドの完了を待ってから実行されます
- エラーが発生しても、デフォルトでは次の行に進みます
実行権限の付与
Shell Script を実行するには、ファイルに実行権限を与える必要があります。
bashchmod +x backup.sh
chmod コマンドは、ファイルの権限を変更するコマンドです。+x は実行権限を追加する意味になりますね。
権限を確認するには以下のコマンドを使います。
bashls -l backup.sh
実行結果の例を見てみましょう。
text-rwxr-xr-x 1 user group 256 Jan 10 12:00 backup.sh
```
`rwxr-xr-x` の部分が権限を表しています。最初の `x` が所有者の実行権限です。
## スクリプトの実行方法
実行権限を付与したスクリプトは、以下の方法で実行できます。
````bash
./backup.sh
カレントディレクトリにあるスクリプトを実行する場合は、./ を付けます。
別の方法として、bash コマンドで直接実行することもできますね。
bashbash backup.sh
この場合は実行権限がなくても実行できます。シバンの指定も無視され、明示的に bash で実行されるわけです。
具体例
例 1: 開発環境のセットアップスクリプト
プロジェクトに新しく参加したメンバーが、開発環境を構築する場面を想定しましょう。
まず、スクリプトファイルを作成します。
bash#!/bin/bash
次に、必要なツールがインストールされているか確認する処理を追加します。
bash# Node.js のバージョン確認
echo "Node.js のバージョンを確認中..."
if ! command -v node &> /dev/null; then
echo "Error: Node.js がインストールされていません"
exit 1
fi
NODE_VERSION=$(node -v)
echo "Node.js ${NODE_VERSION} を検出しました"
command -v は、指定したコマンドが存在するか確認するコマンドです。&> /dev/null は出力を非表示にする記法になりますね。
続いて、依存パッケージのインストール処理を記述します。
bash# パッケージのインストール
echo "依存パッケージをインストール中..."
yarn install
if [ $? -ne 0 ]; then
echo "Error: パッケージのインストールに失敗しました"
exit 1
fi
$? は直前のコマンドの終了ステータスを表す特殊変数です。0 は成功、それ以外は失敗を意味します。
環境変数ファイルの作成も自動化しましょう。
bash# .env ファイルの作成
if [ ! -f .env ]; then
echo ".env ファイルを作成中..."
cp .env.example .env
echo ".env ファイルを作成しました。必要に応じて編集してください。"
else
echo ".env ファイルは既に存在します"
fi
[ ! -f .env ] は「.env ファイルが存在しない場合」という条件式です。
最後に完了メッセージを表示します。
bash# セットアップ完了
echo ""
echo "=============================="
echo "セットアップが完了しました!"
echo "=============================="
echo ""
echo "次のコマンドで開発サーバーを起動できます:"
echo " yarn dev"
このスクリプトを setup.sh として保存すれば、新メンバーは ./setup.sh を実行するだけで環境構築が完了します。
例 2: 定期的なログ管理スクリプト
アプリケーションのログファイルが肥大化するのを防ぐため、古いログを圧縮・削除するスクリプトを作成しましょう。
bash#!/bin/bash
# ログディレクトリの設定
LOG_DIR="/var/log/myapp"
ARCHIVE_DIR="/var/log/myapp/archive"
DAYS_TO_KEEP=7
変数で設定を定義しておくと、後で変更しやすくなりますね。
アーカイブディレクトリが存在しない場合は作成します。
bash# アーカイブディレクトリの作成
if [ ! -d "$ARCHIVE_DIR" ]; then
mkdir -p "$ARCHIVE_DIR"
echo "アーカイブディレクトリを作成しました: $ARCHIVE_DIR"
fi
-d は「ディレクトリが存在するか」を確認する条件です。mkdir -p は親ディレクトリも含めて作成します。
bash# 昨日以前のログファイルを圧縮
echo "古いログファイルを圧縮中..."
find "$LOG_DIR" -name "*.log" -type f -mtime +0 | while read -r logfile; do
filename=$(basename "$logfile")
gzip -c "$logfile" > "$ARCHIVE_DIR/${filename}.gz"
echo "圧縮完了: $filename"
rm "$logfile"
done
find コマンドでログファイルを検索し、while read ループで 1 つずつ処理します。-mtime +0 は「1 日以上前に更新されたファイル」を意味しますね。
最後に、古いアーカイブを削除します。
bash# 指定日数より古いアーカイブを削除
echo "${DAYS_TO_KEEP}日より古いアーカイブを削除中..."
find "$ARCHIVE_DIR" -name "*.gz" -type f -mtime +${DAYS_TO_KEEP} -delete
echo "ログ管理が完了しました"
このスクリプトを cron で定期実行すれば、ログ管理を完全に自動化できます。
例 3: デプロイ前チェックスクリプト
本番環境にデプロイする前に、複数の検証を自動で実行するスクリプトです。
bash#!/bin/bash
# 色付き出力の設定
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
色を使うと、成功・失敗が視覚的にわかりやすくなります。
チェック結果を管理するための変数を初期化します。
bash# チェック結果の初期化
ERRORS=0
Git の状態を確認する処理を追加しましょう。
bash# Git の状態チェック
echo "Git の状態を確認中..."
if [ -n "$(git status --porcelain)" ]; then
echo -e "${RED}✗ コミットされていない変更があります${NC}"
ERRORS=$((ERRORS + 1))
else
echo -e "${GREEN}✓ 作業ディレクトリはクリーンです${NC}"
fi
git status --porcelain は変更があるファイルを簡潔な形式で出力します。-n は「文字列が空でない」を確認する条件ですね。
テストの実行結果を確認します。
bash# テストの実行
echo "テストを実行中..."
yarn test > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ 全てのテストが成功しました${NC}"
else
echo -e "${RED}✗ テストが失敗しました${NC}"
ERRORS=$((ERRORS + 1))
fi
> /dev/null 2>&1 は、標準出力とエラー出力の両方を非表示にする記法です。
TypeScript の型チェックも実行しましょう。
bash# TypeScript の型チェック
echo "型チェックを実行中..."
yarn tsc --noEmit > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ 型エラーはありません${NC}"
else
echo -e "${RED}✗ 型エラーが検出されました${NC}"
ERRORS=$((ERRORS + 1))
fi
最後に、チェック結果をまとめて表示します。
bash# 結果の判定
echo ""
echo "=============================="
if [ $ERRORS -eq 0 ]; then
echo -e "${GREEN}全てのチェックが成功しました!${NC}"
echo "デプロイを実行できます。"
exit 0
else
echo -e "${RED}${ERRORS}個のエラーが検出されました${NC}"
echo "エラーを修正してから再度実行してください。"
exit 1
fi
終了ステータスを適切に設定することで、CI/CD パイプラインと連携しやすくなります。
例 4: 複数サーバーへの一括デプロイ
複数のサーバーに同じ処理を実行する場合のスクリプト例です。
bash#!/bin/bash
# デプロイ対象サーバーのリスト
SERVERS=(
"user@server1.example.com"
"user@server2.example.com"
"user@server3.example.com"
)
配列を使ってサーバーリストを管理します。
デプロイコマンドを定義しましょう。
bash# デプロイコマンドの定義
DEPLOY_COMMAND="cd /var/www/myapp && git pull && yarn install && yarn build && pm2 reload all"
複数のコマンドを && で繋げることで、1 つでも失敗したら後続の処理を中断できますね。
各サーバーに対してループ処理を実行します。
bash# 各サーバーにデプロイ
for server in "${SERVERS[@]}"; do
echo "=============================="
echo "デプロイ先: $server"
echo "=============================="
ssh "$server" "$DEPLOY_COMMAND"
if [ $? -eq 0 ]; then
echo "✓ $server へのデプロイが完了しました"
else
echo "✗ $server へのデプロイが失敗しました"
fi
echo ""
done
"${SERVERS[@]}" は配列の全要素を展開する記法です。ssh コマンドでリモートサーバーに接続し、コマンドを実行します。
デプロイ完了の通知を送る処理も追加できます。
bash# デプロイ完了通知(Slack へ送信する例)
WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
MESSAGE="デプロイが完了しました: $(date '+%Y-%m-%d %H:%M:%S')"
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$MESSAGE\"}" \
"$WEBHOOK_URL"
このようにして、複数サーバーへのデプロイを 1 回のコマンド実行で完了させられます。
まとめ
Shell Script は、コマンドラインでの操作を自動化する強力なツールです。
本記事では、Shell Script の基本から実行モデル、実務で役立つ具体例までご紹介しました。重要なポイントをまとめておきますね。
| # | ポイント | 内容 |
|---|---|---|
| 1 | 自動化の重要性 | 繰り返し作業を Shell Script で自動化すると効率が大幅に向上します |
| 2 | 基本構造 | シバン、変数、コマンドの組み合わせで構成されます |
| 3 | 実行モデル | 上から順番に 1 行ずつ実行され、条件分岐やループも可能です |
| 4 | エラーハンドリング | 終了ステータス($?)を確認して適切に処理します |
| 5 | 活用領域 | 環境構築、ログ管理、デプロイ、サーバー管理など幅広く使えます |
Shell Script を書く際は、以下の点に気を付けると良いでしょう。
まず、コメントを充実させることです。数ヶ月後に見返したときに、何をしているのか理解できるようにしておきますね。
次に、変数で設定を管理することです。スクリプトの冒頭で変数を定義しておけば、後で変更しやすくなります。
そして、エラーハンドリングを忘れないことです。set -e を使えば、エラー発生時に自動的にスクリプトを終了できます。
bash#!/bin/bash
set -e # エラーが発生したら即座に終了
最後に、小さく始めて段階的に拡張することです。最初から複雑なスクリプトを書くのではなく、シンプルなものから始めて、必要に応じて機能を追加していくと良いでしょう。
Shell Script は、一度書けば何度でも使えます。日々の作業で「これ、毎回同じことやってるな」と感じたら、それは Shell Script 化のチャンスですね。
ぜひ、実際に手を動かしてスクリプトを書いてみてください。最初は簡単なものから始めて、徐々に複雑な処理に挑戦していくことで、確実にスキルアップできますよ。
関連リンク
articleComfyUI とは?ノードベースで組む最新画像生成ワークフローを完全解説【2025 年版】
articleBun とは?Node.js・Deno と何が違うのかを 3 分で理解【2025 年最新版】
articleShell Script とは?初心者が最短で理解する基本構文・実行モデル・活用領域
articleNode.js 本番メモリ運用:ヒープ/外部メモリ/リーク検知の継続監視
articleReact とは? 2025 年版の特徴・強み・実務活用を一気に理解する完全解説
articleNext.js でインフィニットスクロールを実装:Route Handlers +`use` で滑らかデータ読込
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来