Webサーバを運用する上で役立ている
- Apacheで有効になっているサイトの設定情報を表示
- 構文を確認
- 問題が無ければApache再起動
- 再起動後にステータスを表示する
スクリプト。非常に便利なものでしたが、VPS新調に際してPHP-FPMを導入。
そこで、
- PHP-FPMも構文チェックを行う
- 他、引数による処理
を改訂しました。(元ネタ:ChatGPT、リファクタリングはdeepseekとGemini)
スクリプト内容
- apache2-check.sh
#!/bin/bash
#================================================================
# Apache & PHP-FPM 管理スクリプト (引数対応版)
#================================================================
#
# 機能:
# 1. Apacheで有効になっているサイトの設定情報を表示します。
# 2. ApacheとPHP-FPMの設定ファイルの構文をチェックします。
# 3. ApacheとPHP-FPMの再起動を個別に確認し、実行します。
# 4. 再起動後に各サービスのステータスを表示します。
#
# 引数:
# -y : 確認プロンプトをすべてスキップし、自動で'yes'と応答します。
# -a : Apacheのみを対象とします。
# -p : PHP-FPMのみを対象とします。
# -h : このヘルプを表示します。
#
#================================================================
# --- 設定項目 ---
# Apacheのサイト設定が格納されているディレクトリ
SITES_DIR="/etc/apache2/sites-enabled"
# 操作対象のPHPバージョン (例: "8.3", "8.2", "7.4")
PHP_VERSION="8.3"
# --- 設定ここまで ---
# --- スクリプトの動作を制御するフラグ ---
AUTO_YES=false
RESTART_APACHE=true # デフォルトでは両方実行
RESTART_PHP=true # デフォルトでは両方実行
EXCLUSIVE_MODE=false # -a または -p が指定されたかを判定するフラグ
# --- ヘルプ表示関数 ---
usage() {
echo "Usage: $(basename "$0") [-y] [-a] [-p] [-h]"
echo " -y : 確認プロンプトをすべてスキップし、自動で'yes'と応答します。"
echo " -a : Apacheのみを対象とします。"
echo " -p : PHP-FPMのみを対象とします。"
echo " -h : ヘルプを表示します。"
echo "引数なしの場合は、ApacheとPHP-FPMの両方が対象となります。"
exit 0
}
# --- 引数解析 ---
while getopts "yaph" opt; do
case $opt in
y)
AUTO_YES=true
;;
a)
if ! $EXCLUSIVE_MODE; then
# -a or -p が初めて指定された場合、排他モードにしてデフォルトをリセット
RESTART_APACHE=false
RESTART_PHP=false
EXCLUSIVE_MODE=true
fi
RESTART_APACHE=true
;;
p)
if ! $EXCLUSIVE_MODE; then
# -a or -p が初めて指定された場合、排他モードにしてデフォルトをリセット
RESTART_APACHE=false
RESTART_PHP=false
EXCLUSIVE_MODE=true
fi
RESTART_PHP=true
;;
h)
usage
;;
\?)
# 不正なオプション
usage
;;
esac
done
# PHP-FPMのサービス名とコマンド名を変数から生成
PHP_FPM_SERVICE="php${PHP_VERSION}-fpm"
PHP_FPM_COMMAND="php-fpm${PHP_VERSION}"
#
# サービスを再起動し、ステータスを表示する関数
#
restart_and_check_service() {
local service_name="$1"
local service_label="$2" # 表示用の名前
local confirm_action="n"
if [ "$AUTO_YES" = true ]; then
confirm_action="y"
echo "${service_label} を再起動します... (-yオプションにより自動確認)"
else
read -p "${service_label} を再起動しますか? (y/n): " confirm_action
fi
if [[ "$confirm_action" =~ ^[Yy]$ ]]; then
if [ "$AUTO_YES" = false ]; then
echo "--- ${service_label} を再起動します... ---"
fi
if ! systemctl restart "$service_name"; then
echo "エラー: ${service_label} の再起動に失敗しました。"
else
echo "${service_label} が正常に再起動されました。"
echo
echo "==== ${service_label} ステータス ===="
systemctl status "$service_name" --no-pager
echo "=================================="
fi
else
echo "${service_label} の再起動はキャンセルされました。"
fi
echo
}
# スクリプトを root ユーザーで実行しているかチェック
if [ "$EUID" -ne 0 ]; then
echo "エラー: このスクリプトは root 権限で実行する必要があります。"
exit 1
fi
# 1. 有効なサイト設定とドメインを表示
# このセクションは引数に関わらず常に表示される情報として実行します
echo "==== 有効なサイト設定ファイル ===="
if [ -z "$(ls -A "$SITES_DIR" 2>/dev/null)" ]; then
echo "サイト設定が存在しません。"
else
shopt -s nullglob
for site in "$SITES_DIR"/*; do
echo "設定ファイル: $(basename "$site")"
entries=$(grep -hi -E "^\s*(ServerName|ServerAlias)\s+" "$site" | sed -E 's/^[[:blank:]]+//;s/[[:blank:]]*#.*//' | awk '{
original_directive = $1
directive = tolower(original_directive)
proper_directive = (directive == "servername") ? "ServerName" : \
(directive == "serveralias") ? "ServerAlias" : original_directive
for (i=2; i<=NF; i++) {
domain = tolower($i)
sub(/[;,]*$/, "", domain)
gsub(/^[[:blank:]]+|[[:blank:]]+$/, "", domain)
if (domain) {
printf "%s %s\n", proper_directive, domain
}
}
}' | sort -u)
if [ -z "$entries" ]; then
echo " ※ ServerName/ServerAliasが定義されていません"
else
echo "$entries" | sed 's/^/ /'
fi
echo
done
shopt -u nullglob
fi
echo "=================================="
echo
# 2. 構文チェック
echo "--- 構文チェック ---"
SYNTAX_OK=true
# Apache構文チェック
if [ "$RESTART_APACHE" = true ]; then
echo "Apache の構文をチェックしています..."
if ! apachectl configtest 2>&1 | grep -q "Syntax OK"; then
echo "エラー: Apacheの構文エラーが検出されました。"
apachectl configtest # エラー詳細を再表示
SYNTAX_OK=false
else
echo "Apacheの構文は正常です。"
fi
echo
fi
# PHP-FPMの存在確認と構文チェック
PHP_FPM_ENABLED=false
if [ "$RESTART_PHP" = true ]; then
if systemctl list-units --type=service --all | grep -q "${PHP_FPM_SERVICE}.service"; then
if command -v "$PHP_FPM_COMMAND" &>/dev/null; then
PHP_FPM_ENABLED=true
echo "${PHP_FPM_SERVICE} の構文をチェックしています..."
if ! "$PHP_FPM_COMMAND" -t 2>&1 | grep -q "test is successful"; then
echo "エラー: ${PHP_FPM_SERVICE} の構文エラーが検出されました。"
"$PHP_FPM_COMMAND" -t # エラー詳細を再表示
SYNTAX_OK=false
else
echo "${PHP_FPM_SERVICE} の構文は正常です。"
fi
else
echo "警告: ${PHP_FPM_SERVICE} サービスは存在しますが、${PHP_FPM_COMMAND} コマンドが見つかりませ
ん。PHP-FPMのチェックはスキップします。"
RESTART_PHP=false # 実行フラグをオフにする
fi
else
echo "情報: ${PHP_FPM_SERVICE} サービスが見つかりません。PHP-FPM関連の処理はスキップします。"
RESTART_PHP=false # 実行フラグをオフにする
fi
echo
fi
# 構文エラーがあれば処理を中断
if [ "$SYNTAX_OK" = false ]; then
echo "構文エラーが検出されたため、処理を中断します。"
exit 1
fi
echo "--------------------"
echo
# 3. サービスの再起動
if [ "$RESTART_APACHE" = false ] && [ "$RESTART_PHP" = false ]; then
echo "再起動対象のサービスがありません。"
exit 0
fi
# Apacheの再起動
if [ "$RESTART_APACHE" = true ]; then
restart_and_check_service "apache2" "Apache"
fi
# PHP-FPMの再起動
if [ "$RESTART_PHP" = true ] && [ "$PHP_FPM_ENABLED" = true ]; then
restart_and_check_service "$PHP_FPM_SERVICE" "$PHP_FPM_SERVICE"
fi
スクリプトの動き
sudo bash apache2-check.sh
とすることで- A@acheを起動するか、PHP-FPMを起動するかの2択が生まれます。
-y
オプションの場合は全てyにしてプロンプトを省略します。-a
でApacheのみの再起動-p
はPHP-FPMのみの再起動
と、柔軟かつやりやすいスタイルへと仕上がりました。
コメントを残す