コーディング規約のないシェルスクリプトは、書いた本人ですら半年後には読めなくなることがあります。変数名の命名スタイルが人によって異なり、インデントが混在し、コメントがどこにも書かれていない——そういったスクリプトを引き継いだとき、改修コストは新規作成の何倍にもなります。
この記事では、RHEL 9系/Ubuntu 22.04 LTS以降の環境を想定し、シェルスクリプトのコーディング規約をチームで統一するためのスタイルガイドの作り方を解説します。変数名の命名規則から、インデント・クォート・コメントの書き方、local宣言と関数分割の設計、そしてshellcheckとエディタ設定で規約を機械的に守らせる仕組みの構築まで説明します。
この記事のポイント
・変数名は大文字=グローバル・小文字=ローカルの使い分けが核心
・インデントはスペース4つ固定・クォートはダブルクォートを基本に
・コメントはヘッダ・セクション境界・非自明な処理の3か所に限定
・shellcheckと.editorconfigとCIで規約を機械的に強制する
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜシェルスクリプトにコーディング規約が必要なのか
シェルスクリプトはコンパイルエラーが出ない分、スタイルに関するエラーが発生しないまま属人化が進みます。「動けばいい」で書き続けると、次のような問題が積み重なります。・変数名に
TMPDIR(大文字)と tmp_dir(小文字)が混在し、スクリプトをつないだ瞬間に衝突する・インデントにスペースとタブが混在し、一部のエディタで見た目が崩れる
・関数が100行を超えてネストが深くなり、どこでエラーが出ているか追えなくなる
・クォートが省略されたままで、パス名にスペースが入ると予期しない挙動をする
コーディング規約は「美しく書くための規則」ではなく、「保守できる状態を維持するための最低限の取り決め」です。チームの人数が増えるほど、また同じスクリプトを長期間使い続けるほど、その価値は高まります。
スタイルガイドファイルの構成|ファイル冒頭のヘッダ規約
規約をドキュメントにまとめる前に、まずスクリプト自体の冒頭を統一しましょう。ファイル冒頭のヘッダはスクリプトの「自己紹介文」として機能します。以下は標準的なヘッダの例です。
#!/bin/bash # ============================================================================= # スクリプト名 : backup_db.sh # 用途 : PostgreSQLの日次バックアップ # 引数 : なし # 前提条件 : pg_dump コマンドが PATH に含まれていること # 最終更新 : 2026-10-25 # 作成者 : ops-team # =============================================================================
・スクリプト名:ファイル名と一致させる
・用途:1行で何をするスクリプトか書く
・引数:位置パラメータとオプションを列挙
・前提条件:依存コマンド・必要なファイルなど
・最終更新:ISO 8601形式(YYYY-MM-DD)で統一
・作成者:個人名よりチーム名やメールアドレスが保守しやすい
「最終更新」に更新者名を含めるかどうか、Gitで管理しているならコメントの重複を避けてシンプルにするかどうかは、チームの運用スタイルに合わせて決めます。重要なのは「どのチームのスクリプトも同じ形式で始まる」という統一です。
変数名の命名規則|シェルスクリプトの大文字と小文字の使い分け
シェルスクリプトの変数命名で最初に取り決めるべきは「大文字と小文字の使い分け」です。一般的に採用されているルールは次のとおりです。| 種類 | 命名規則 | 例 |
|---|---|---|
| 環境変数・グローバル定数 | UPPER_SNAKE_CASE | BACKUP_DIR="/var/backup" |
| スクリプト内グローバル変数 | UPPER_SNAKE_CASE | LOG_FILE="/var/log/backup.log" |
| 関数内ローカル変数 | lower_snake_case | local target_file="$1" |
| ループカウンタ・一時変数 | lower_snake_case | local i=0 |
また、シェルの組み込み環境変数(
HOME/PATH/IFS など)もすべて大文字です。誤って PATH を上書きしてしまうようなミスを防ぐため、グローバル変数には APP_LOG_DIR のようにアプリ固有のプレフィックスを付けるプロジェクトもあります。チームで決めた基準を規約文書に明記しておきましょう。シェルスクリプトのインデントとクォートの統一
1. インデント幅の選択
推奨はスペース4つ固定です。理由はシンプルです。・タブ文字はエディタによって表示幅が2・4・8と異なり、コードレビュー時に見た目が変わる
・スペース2つはネストが深くなったとき視認性が下がる
・スペース4つはPythonをはじめ多くの言語と一致しており、複数言語を扱うエンジニアが読みやすい
.editorconfig を使えば、エディタを問わずインデント設定を強制できます(後述)。
2. クォートの統一原則
クォートの規約は「基本ダブルクォート・例外シングルクォート」が一般的です。# OK: 変数展開が必要なケースはダブルクォート echo "バックアップ先: ${BACKUP_DIR}" cp "$source_file" "$target_file" # OK: リテラル文字列でドル記号をそのまま使いたい場合はシングルクォート pattern='\.(log|txt)$' awk '{print $1}' /etc/passwd | grep -E "$pattern" # NG: クォートなしは空白・グロブ展開で予期しない分割が起きる cp $source_file $target_file
コメントの書き方|シェルスクリプトを自己文書化する
コメントの書き方で一番よくある失敗は「コードを日本語訳したコメント」を大量に書いてしまうことです。# NG: コードを読めば分かることをコメントにしている i=0 # i を 0 に初期化 i=$((i+1)) # i に 1 を加算
1. ファイルヘッダコメント
スクリプトの用途・前提・更新情報を記述する(前述のヘッダ規約を参照)。2. セクション境界コメント
スクリプトが長い場合、機能の区切りを明示します。# --- 初期化・引数チェック ----------------------------------------------- parse_args() { :; } check_prerequisites() { :; } # --- バックアップ処理 --------------------------------------------------- run_backup() { :; } rotate_old_files() { :; } # --- メイン処理 --------------------------------------------------------- main() { :; }
3. 非自明な処理へのコメント
なぜそのコードを書いたのかが分かりにくい箇所だけコメントを付けます。# find の -prune はマッチしたディレクトリの中まで降りないオプション。 # -delete と組み合わせると意図しないファイルを消す恐れがあるため # 削除は別コマンドで行う(shellcheckのSC2184対応)。 find "$LOG_DIR" -maxdepth 1 -name "*.log" -mtime +30 -print0 | xargs -0 rm -f
local宣言と関数分割の設計
1. local宣言を徹底する理由
シェルスクリプトで関数内の変数はデフォルトでグローバルスコープです。local をつけ忘れると、同名の変数が別の関数と衝突し、追いにくいバグの原因になります。# NG: local を付け忘れると result がグローバルに漏れる calc_size() { result=$(du -sh "$1" | cut -f1) echo "$result" } # OK: local で関数内に閉じ込める calc_size() { local result result=$(du -sh "$1" | cut -f1) echo "$result" }
local で一括宣言する」と決めると、レビューが楽になります。shellcheck は local のない変数代入に SC2034 などの警告を出すため、静的解析とセットで運用するのが効果的です。2. 関数の粒度と命名規則
関数の粒度の目安は「1関数=1つの明確な役割・30行以内」です。それを超えるようなら、内部の処理をさらに関数に切り出します。命名規則は動詞_目的語の lower_snake_case を推奨します。
・
run_backup — バックアップを実行する・
check_disk_space — ディスク空き容量を確認する・
rotate_logs — ログをローテーションする「何をするか」が関数名から読み取れると、コメントを付けなくてもコードが自己説明的になります。チームでシェルスクリプトを体系的に学ぶ場合は、シェルスクリプト実践講座のような構造化された学習リソースで設計の考え方を統一しておくと、メンバー間の認識ズレが減ります。
shellcheckとエディタ設定でシェルスクリプトの規約を機械的に守らせる方法
規約をドキュメントだけで運用しようとすると、レビューでの指摘漏れや属人的な判断が残ります。機械的に強制する仕組みを先に整えることが、長期運用のカギです。1. shellcheckによる静的解析
shellcheck はシェルスクリプトの静的解析ツールで、クォートの抜け・local 忘れ・$()の書き方の違いなど、規約に直結するチェックをしてくれます。# RHEL 9系でのインストール例 sudo dnf install -y ShellCheck # スクリプトを解析する shellcheck backup_db.sh # 出力例(環境により異なります) # In backup_db.sh line 14: # cp $source_file $target_file # ^-- SC2086: Double quote to prevent globbing and word splitting.
2. .editorconfigでインデントを統一する
.editorconfig をリポジトリのルートに置くと、VS Code・Vim・JetBrains IDEなどほぼすべてのエディタで設定を共有できます。# .editorconfig の例 root = true [*] charset = utf-8 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true [*.sh] indent_style = space indent_size = 4
3. CIへの組み込み
GitHub Actions や GitLab CI に shellcheck を組み込むと、プルリクエスト時に自動でチェックが走ります。# .github/workflows/shellcheck.yml の例 name: ShellCheck on: [push, pull_request] jobs: shellcheck: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run ShellCheck uses: ludeeus/action-shellcheck@master
シェルスクリプトのコーディング規約のまとめ
シェルスクリプトのコーディング規約を設計するポイントをまとめます。| 規約項目 | 推奨スタイル |
|---|---|
| ファイルヘッダ | スクリプト名・用途・引数・前提条件・最終更新を統一フォーマットで記載 |
| グローバル変数・定数 | UPPER_SNAKE_CASE |
| 関数内ローカル変数 | lower_snake_case + local宣言を関数冒頭に集約 |
| インデント | スペース4つ固定(タブ禁止) |
| クォート | 変数参照はダブルクォート基本・リテラル文字列はシングルクォート |
| コメント | ヘッダ・セクション境界・非自明な処理の3か所に限定 |
| 関数命名 | 動詞_目的語の lower_snake_case・30行以内を目安に分割 |
| 機械チェック | shellcheck + .editorconfig + CI自動実行の3点セット |
>> シェルスクリプト実践講座の詳細はこちら
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:シェルスクリプトのヘルプ表示設計|--helpと--versionとusage関数で使い方を自己文書化する方法
- この記事の属するカテゴリ:シェルスクリプトへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます