case文を活用したシステム管理シェルスクリプトの構築手法

シェルスクリプトにおける条件分岐において、case文は複数のコマンドライン引数を効率的にルーティングするための標準的な構文です。本稿では、実際のサーバー運用環境で頻繁に要求される「Webサーバープロセスの制御」と「認証情報ファイルの安全な管理」を題材に、保守性と堅牢性を考慮した実装アプローチを解説します。

Nginxプロセスの起動・停止管理スクリプト

従来のSysVinit互換スクリプトとして動作させるためには、chkconfigコメントヘッダーの定義と、標準的な終了コードの返却が必須要件となります。プロセスの実行状態は単にPIDファイルの存在を確認するだけでなく、実際にカーネル上でプロセスが生存しているかをシグナル検証で確認する構成に設計します。

スクリプト本体は以下のように実装します。

#!/bin/sh
# chkconfig: 2345 50 50
# description: Manages Nginx HTTP server lifecycle

NGINX_BIN="/usr/local/nginx/sbin/nginx"
PID_PATH="/usr/local/nginx/logs/nginx.pid"
RETURN_CODE=0
. /etc/init.d/functions

verify_status() {
    if [ -s "$PID_PATH" ] && kill -0 "$(cat "$PID_PATH")" 2>/dev/null; then
        return 0
    fi
    return 1
}

execute_start() {
    if verify_status; then
        echo "Nginx process is already active."
        return 0
    fi
    $NGINX_BIN
    RETURN_CODE=$?
    if [ $RETURN_CODE -eq 0 ]; then
        action "Starting Nginx service" /bin/true
    else
        action "Starting Nginx service" /bin/false
    fi
    return $RETURN_CODE
}

execute_stop() {
    if ! verify_status; then
        echo "Nginx process is not running."
        return 1
    fi
    $NGINX_BIN -s stop
    RETURN_CODE=$?
    if [ $RETURN_CODE -eq 0 ]; then
        action "Stopping Nginx service" /bin/true
    else
        action "Stopping Nginx service" /bin/false
    fi
    return $RETURN_CODE
}

case "$1" in
    start)
        execute_start
        ;;
    stop)
        execute_stop
        ;;
    restart|reload)
        execute_stop
        sleep 1
        execute_start
        ;;
    *)
        echo "Usage: $(basename $0) {start|stop|restart|reload}"
        exit 1
        ;;
esac
exit $RETURN_CODE

実装上では、verify_status関数内でファイルの存在チェックとkill -0によるシグナル検証を組み合わせ、プロセス終了後の残留PIDファイルによる誤判定を防止しています。/etc/init.d/functionsが提供するactionヘルパーを呼び出すことで、システム標準の出力フォーマット(成功時は緑色の[OK]、失敗時は赤色の[FAILED])を統一しています。各操作関数は正確な終了ステータスを返すように設計されており、chkconfigや外部プロセス監視ツールとの連携安定性を確保しています。

認証リストファイルのユーザー管理スクリプト

平文で管理される認証リストに対して、安全な追加・削除・検索操作を実現するには、ファイルレベルの不変属性制御と厳密な文字列マッチングが不可欠です。特にgrepによる部分一致を排除し、意図しないレコードの誤操作を防ぐ構成を採用します。

管理スクリプトは以下のように構築します。

#!/usr/bin/env bash
set -euo pipefail

AUTH_DB="/etc/openvpn_authfile.conf"

# 管理者権限の検証
if [ "$(id -u)" -ne 0 ]; then
    echo "Error: Root privileges are mandatory for database modification." >&2
    exit 1
fi

usage_info() {
    echo "Usage: $(basename "$0") {-add|-del|-search} <username>"
    exit 2
}

[ $# -ne 2 ] && usage_info

# ファイル初期化とロック解除
unlock_db() {
    touch "$AUTH_DB" 2>/dev/null
    chattr -i "$AUTH_DB" 2>/dev/null || true
}

# ファイル保護と同期
lock_db() {
    sync
    chattr +i "$AUTH_DB" 2>/dev/null || true
}

operation="$1"
target="$2"

case "$operation" in
    -add|--create)
        unlock_db
        # 完全一致による重複チェック
        if grep -qxF "$target" "$AUTH_DB"; then
            echo "Error: User '$target' already exists."
            lock_db
            exit 3
        fi
        cp -p "$AUTH_DB" "${AUTH_DB}.backup.$(date +%Y%m%d%H%M%S)"
        echo "$target" >> "$AUTH_DB"
        [ $? -eq 0 ] && echo "Success: Added '$target' to authentication list."
        lock_db
        ;;
    -del|--remove)
        unlock_db
        if ! grep -qxF "$target" "$AUTH_DB"; then
            echo "Error: User '$target' not found in database."
            lock_db
            exit 3
        fi
        cp -p "$AUTH_DB" "${AUTH_DB}.backup.$(date +%Y%m%d%H%M%S)"
        sed -i "/^${target}\$/d" "$AUTH_DB"
        [ $? -eq 0 ] && echo "Success: Removed '$target' from authentication list."
        lock_db
        ;;
    -search|--find)
        if grep -qxF "$target" "$AUTH_DB"; then
            echo "Result: '$target' is currently registered."
        else
            echo "Result: '$target' is not present in the list."
        fi
        exit 0
        ;;
    *)
        usage_info
        ;;
esac

本スクリプトでは、grep -qxFオプションを適用し、行全体かつ固定文字列として完全一致を検索します。これにより、類似したユーザー名(例:adminadministrator)の混同による誤削除・誤登録を完全に排除しています。ファイル書き込み処理の前後にchattr -i/+iを適用することで、root権限を持つプロセスであっても直接のecho >rmによる破壊的変更を防ぎます。また、set -euo pipefailによる厳格なエラー制御と、タイムスタンプ付与によるバックアップ生成を組み合わせており、操作のトレーサビリティとスクリプトの実行安定性を両立させています。

タグ: shell-scripting sysvinit-scripts nginx-administration bash-programming file-attribute-management

6月29日 16:32 投稿