RHEL系Linuxで複数のサービスを管理していると、systemctlコマンドによる起動・停止の操作を何度も繰り返す場面が出てきます。Apache(httpd)やSSH、chronyd、PostgreSQLなど、制御対象が増えるほど入力作業が煩雑になり、運用ミスや確認漏れの原因にもなります。
今回紹介する「サービス制御スクリプト(manage_service.sh)」は、そんな日常の繰り返し作業を一元化・簡略化するために開発した汎用スクリプトです。-s でサービス名、-c で操作コマンドを指定するだけで、systemd管理下の任意サービスを柔軟に制御できます。
サーバーごとに異なるサービスを一括で管理したい方、自作スクリプトや自動化ツールに組み込みたい方に最適な構成です。
汎用サービススクリプトの概要と活用の狙い
このスクリプトは、自分自身の開発環境で複数のsystemdサービスを効率よく制御するために作成したものです。ApacheやSSH、chronydなどのサービスを日常的に操作する中で、コマンドを毎回打ち込む煩雑さやサービス名の打ち間違いによるミスを防ぎたいという目的から設計しました。単一のスクリプトで、任意のサービスを起動・停止・再起動・ステータス確認まで柔軟に制御できる点が最大の特徴です。
この「汎用サービススクリプト(manage_service.sh)」は、サービス名とコマンドを引数で指定することで、任意のsystemdサービスを制御できます。実際の運用現場では、一度書いたスクリプトを複数の環境で再利用する機会が多いため、汎用性と可読性、そして引数による柔軟性に重点を置いています。
スクリプトの基本的な目的
本スクリプトの主な目的は、systemdで管理されている複数のサービスを共通の構文で制御できるようにし、オペレーションの一貫性と効率性を高めることです。操作対象となるサービスは、Apache(httpd)やPostgreSQL(postgresql)、cron、sshd、chronydなど、RHEL系Linuxにおいて日常的に管理するものが中心です。
複数のサービスを順番に制御する場合でも、スクリプト内で引数を指定して呼び出すだけで済むため、手動操作よりも遥かに効率的です。特にシェルスクリプトによる構成管理や自動化処理との親和性も高く、他の処理と組み合わせることでさらに効果を発揮します。
systemctlを使った制御との違い
systemctlコマンド自体は非常に優れたサービス管理ツールですが、直接利用する場合はどうしても冗長になりがちです。たとえば、サービス名やオプションを都度打ち込む必要があり、入力ミスや確認漏れによるヒューマンエラーの原因になります。
本スクリプトでは、以下のように-sと-cオプションを明示的に指定することで、対象サービスと実行コマンドを簡潔に指定できます。
sh manage_service.sh -s httpd -c start
sh manage_service.sh -s sshd -c status
このように、引数を統一した形式で受け付けることで、外部から他のスクリプトやバッチ処理で呼び出す際にも極めて扱いやすくなります。ログ出力もすべてlogger.shrcに準拠しているため、出力形式の整合性も保たれます。
現場での利用シーンの具体例
このスクリプトは、以下のような運用現場で実際に活用されています。
利用シーン | 目的 | 対象サービス例 |
---|---|---|
開発環境の初期構築 | 初回起動と状態確認 | httpd, postgresql, chronyd |
定期的なサービス再起動 | 夜間バッチ後の安定化 | sshd, crond |
テスト時の手動操作代替 | GUIなしでの制御 | httpd, tomcat, docker |
スクリプト連携による自動化 | 複数サービスを一括制御 | 任意 |
特にRHEL系の開発環境では、ApacheとPostgreSQLの組み合わせで動作するWebシステムが多く、これらのサービスを起動・停止する操作を繰り返す場面が日常的に発生します。cronで定期的に再起動を行いたい場合にも、このスクリプトを呼び出すことで容易に実装できます。
開発サーバーのメンテナンス時に、手動でsystemctlを使う代わりにこのスクリプトを使うことで、ヒューマンエラーの抑制と工数削減を両立できます。
スクリプトの構成と設計の基本
このスクリプトは、単なるsystemctlのラッパーではなく、拡張性と保守性を意識した構成になっています。開発現場で使いまわすことを前提に、変数・関数・ロギング・終了コードまで標準化されています。スクリプトの記述方式やファイル構成も他のツール群と共通化しておくことで、管理対象が増えても柔軟に対応できます。
ファイル構成と配置ルール
スクリプトはプロジェクトの共通構成に従い、以下のディレクトリに分割して配置しています。loggerやutilsなどの共通部品と分けることで、メンテナンスしやすい状態を保ちます
パス | 用途 | 補足 |
---|---|---|
bin/manage_service.sh | メインスクリプト | サービス制御処理 |
com/logger.shrc | ログ出力共通処理 | logOut/exitLogなど |
com/utils.shrc | ユーティリティ関数 | isProcessAliveなど |
このように機能単位でファイルを分離しておくことで、今後スクリプトが増えてもログ仕様やエラーハンドリングの書き直しが不要になります。
ログ出力の設計とlogger.shrcとの連携
すべてのログはlogger.shrcを通じて出力され、出力形式とログレベルが統一されています。これは開発・検証・本番といった環境に関係なく、同じ出力ルールで記録を残せることを意味します。
例えば、サービス起動時に表示されるログは以下のような形式になります。
2025-07-24 13:10:12 [ INFO ] Starting sshd...
2025-07-24 13:10:14 [ INFO ] sshd is running.
このように、出力はタイムスタンプ+ログレベル+メッセージの順に統一されているため、ログ監視やgrepでの抽出もしやすくなっています。
引数処理とgetoptsによる拡張性
スクリプトはgetoptsを使ってオプション引数を柔軟に受け付けるように設計されています。引数の順序や省略に左右されないため、上位スクリプトから呼び出す際にも一貫性があります。
指定できるオプションは以下の2つです。
-sオプション(サービス名指定)
サービス名は必須であり、systemdで認識されているサービス名をそのまま指定します。例として、Apacheであれば「httpd」、SSHであれば「sshd」となります。
sh manage_service.sh -s httpd -c restart
-cオプション(操作コマンド指定)
操作コマンドには、start・stop・restart・status・graceful・graceful-stopのいずれかを指定します。gracefulはsystemctl reloadに相当し、graceful-stopはstopにフォールバックする仕組みになっています。
sh manage_service.sh -s chronyd -c graceful
これにより、必要最小限の引数で安全かつ確実なサービス制御が可能になります。引数が不足している場合はエラーメッセージとともにヘルプを自動表示するため、誤操作も防げます。
スクリプトの利用方法と具体的な実行例
このスクリプトは、systemctlによるサービス制御をより簡潔に扱うために設計されています。オプションでサービス名と制御コマンドを指定するだけで、複数のサービスを対象にした再起動や状態確認などの運用業務を安全かつ統一的に行えます。ここでは、基本的な操作方法とともに、実際の使用例を交えて紹介します。
前提となる実行環境
Beエンジニアでシェルスクリプトを実行する環境は下記の通りとします。
実行環境
BASE_DIR(任意のディレクトリ)
- scripts
- bin(実行スクリプト格納領域)
- <<各種実行スクリプト>>.sh (実行ファイル)
- com(共通スクリプト格納領域)
- logger.shrc(共通ログ出力ファイル)
- utils.shrc(共通関数定義ファイル)
- etc(設定ファイル等の格納領域)
- infraMessage.conf(メッセージ定義ファイル)
- log(スクリプト実行ログの格納領域)
- スクリプト名.log
- tmp(テンポラリ領域)
- rep(レポート出力領域)
- bin(実行スクリプト格納領域)
サービス制御スクリプト
サービス制御スクリプト(manage_service.sh)の全文を以下に掲載します。このスクリプトは、systemctlで管理されている任意のサービスに対して、起動・停止・再起動・状態確認・graceful再読み込みといった操作を安全に実行できるよう設計されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
#!/bin/sh #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ # # manage_service.sh # ver.1.1.0 2025.07.24 # # Usage: # sh manage_service.sh -s <service_name> -c <command> # # Description: # 任意の systemd サービスを制御する汎用スクリプト(getopts対応) # - ログ出力に対応(logger.shrc 準拠) # - 使用例: # sh manage_service.sh -s httpd -c start # sh manage_service.sh -s sshd -c status # #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ # <変更履歴> # Ver. 変更管理No. 日付 更新者 変更内容 # 1.0 〇〇〇〇〇 2025/07/24 Bepro getopts対応/ファイル名変更 #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ # ------------------------------------------------------------------ # 初期処理 # ------------------------------------------------------------------ . "$(dirname "$0")/../com/utils.shrc" . "$(dirname "$0")/../com/logger.shrc" setLANG utf-8 # ======================================== # 定数定義 # ======================================== readonly JOB_OK=0 readonly JOB_WR=1 readonly JOB_ER=2 # ------------------------------------------------------------------ # variables (変数の宣言領域) # ------------------------------------------------------------------ scope="var" rc=0 SERVICE_NAME="" CMD="" # ---------------------------------------------------------- # functions (関数を記述する領域) # ---------------------------------------------------------- scope="func" # 使い方表示 usage() { cat << EOF -------------------------------------- Usage: sh manage_service.sh -s <service_name> -c <command> Options: -s service_name : 対象の systemd サービス名 -c command : Specify operation mode(start|stop|restart|graceful|graceful-stop|status) Commands: launch - Launch the process shutdown - Terminate the process cycle - Restart it cleanly reload - Apply configuration changes (if applicable) soft-stop - Attempt soft stop (fallback: force stop) inspect - Display current operational status -------------------------------------- Example: sh manage_service.sh -s httpd -c start sh manage_service.sh -s sshd -c status EOF } # サービスの起動状態を確認 isServiceRunning() { systemctl is-active --quiet "$1" return $? } # サービスの状態を表示 displayStatus() { local service="$1" if isServiceRunning "$service"; then logOut "INFO" "$service is running." else logOut "INFO" "$service is not running." fi } # ------------------------------------------------------------------ # pre-process (事前処理ロジックを記述する領域) # ------------------------------------------------------------------ scope="pre" # getopts while getopts "s:c:" opt; do case "$opt" in s) SERVICE_NAME="$OPTARG" ;; c) CMD="$OPTARG" ;; *) usage; exit 2 ;; esac done startLog logOut "INFO" "Args: [-s $SERVICE_NAME -c $CMD]" trap ":" 1 2 3 15 # 入力チェック if [ -z "$SERVICE_NAME" ] || [ -z "$CMD" ]; then logOut "ERROR" "引数が不足しています。" usage exitLog ${JOB_ER} fi # ------------------------------------------------------------------ # main-process (メインロジックを記述する領域) # ------------------------------------------------------------------ scope="main" case "$CMD" in start) if isServiceRunning "$SERVICE_NAME"; then logOut "WARNING" "$SERVICE_NAME is already running." else logOut "INFO" "Starting $SERVICE_NAME..." systemctl start "$SERVICE_NAME" fi ;; stop) if ! isServiceRunning "$SERVICE_NAME"; then logOut "WARNING" "$SERVICE_NAME is already stopped." else logOut "INFO" "Stopping $SERVICE_NAME..." systemctl stop "$SERVICE_NAME" fi ;; restart) logOut "INFO" "Restarting $SERVICE_NAME..." systemctl restart "$SERVICE_NAME" ;; graceful) logOut "INFO" "Reloading $SERVICE_NAME..." systemctl reload "$SERVICE_NAME" ;; graceful-stop) logOut "INFO" "Graceful stop not supported. Falling back to stop..." systemctl stop "$SERVICE_NAME" ;; status) displayStatus "$SERVICE_NAME" ;; *) logOut "ERROR" "Invalid command: [$CMD]" usage exitLog ${JOB_ER} ;; esac sleep 1 if [ "$CMD" != "status" ]; then displayStatus "$SERVICE_NAME" fi # ---------------------------------------------------------- # post-process (事後処理ロジックを記述する領域) # ---------------------------------------------------------- scope="post" exitLog $rc |
すべてのログ出力はlogger.shrcに準拠しており、運用現場での再利用や他スクリプトとの統合にも対応しています。
スクリプトを任意のディレクトリに配置し、実行権限を付与すればすぐに使用可能です。必要に応じてパスやサービス名の初期値をカスタマイズしてください。
起動・停止・再起動の基本操作
基本的な操作は非常にシンプルです。-sオプションでサービス名、-cオプションで制御コマンドを指定するだけで、該当するsystemdサービスを安全に制御できます。
起動コマンドは以下のようになります。
sh manage_service.sh -s httpd -c start
停止は次の通りです。
sh manage_service.sh -s httpd -c stop
再起動はrestartオプションを指定します。
sh manage_service.sh -s httpd -c restart
スクリプト内部でサービスの状態確認を自動で行うため、すでに起動している場合や停止している場合は、警告ログを出力するだけで処理を中断できます。これにより、無駄な再起動や誤操作を防げます。
サービスの状態確認
statusオプションを使用することで、サービスが現在起動中かどうかを確認できます。これはsystemctl is-activeと同等の動作を行います。
sh manage_service.sh -s sshd -c status
この実行結果は、以下のようにログ出力されます。
2025-07-24 10:15:41 [ INFO ] sshd is running.
ログ出力フォーマットはlogger.shrcに準拠しているため、他のスクリプトとも整合性が保たれます。
graceful・graceful-stopとの違い
gracefulとgraceful-stopは、通常のrestartやstopとは動作が異なります。gracefulはsystemctl reloadに対応し、プロセスを完全に終了せず設定ファイルの再読み込みだけを行います。
sh manage_service.sh -s httpd -c graceful
一方、graceful-stopは現状ではsystemctl stopにフォールバックする仕様となっています。将来的に、SIGQUITなどの優雅なシャットダウンをサポートする機能に拡張することも視野に入れています。
sh manage_service.sh -s httpd -c graceful-stop
どちらも、既存プロセスへの影響を最小限に抑えたい場合に使用すると効果的です。
主要サービスに対する実行サンプル
代表的なsystemdサービスに対して、本スクリプトでよく使うコマンド例を一覧にまとめました。サービスごとの操作を統一的に扱える点が最大の利点です。
サービス | 用途 | 実行例 |
---|---|---|
Apache(httpd) | 設定変更後の再起動 | sh manage_service.sh -s httpd -c restart |
Apache(httpd) | 設定の反映のみ | sh manage_service.sh -s httpd -c graceful |
SSH(sshd) | 状態確認 | sh manage_service.sh -s sshd -c status |
SSH(sshd) | 設定変更時の再起動 | sh manage_service.sh -s sshd -c restart |
chronyd | 時刻同期の確認 | sh manage_service.sh -s chronyd -c status |
chronyd | 設定再読み込み | sh manage_service.sh -s chronyd -c graceful |
サービス制御スクリプトのメリットと応用
manage_service.shは単なるコマンドの短縮ツールではなく、日々の運用や保守を効率化するための実践的な仕組みとして設計されています。ここではこのスクリプトがもたらす具体的な利点と、他のシェルスクリプトと組み合わせた応用可能性について解説します。
繰り返し作業の自動化
システム管理において、サービスの起動・停止・ステータス確認といった操作は繰り返し発生します。特に開発環境やテスト環境では、複数サービスを起動してから検証を始める場面が多くなります。
このスクリプトを使えば、以下のように複数のサービスを一括で起動させる処理も簡単に実現できます。
sh manage_service.sh -s httpd -c start
sh manage_service.sh -s postgresql -c start
sh manage_service.sh -s sshd -c start
これらを1つのバッチスクリプトにまとめて実行することで、起動順序や確認の手間を省略できます。cronに組み込むことで、夜間の定期再起動や週末の構成リセットなど、幅広い運用業務を自動化できます。
スクリプト共通化による保守性向上
manage_service.shでは、ログ出力やエラーハンドリングの形式が共通化されています。そのため、同じ設計思想に基づいて構成された他のスクリプト群と容易に統合することが可能です。
特にlogger.shrcによるログ制御は、システム全体のトレース性を高めるうえで重要です。すべてのログが一貫した形式で出力されるため、ログ解析やトラブル調査においても役立ちます。
仮にサービス名の変更やスクリプトの拡張が発生した場合でも、構造が明確なため修正が1か所で済むケースが多く、保守の負担を最小限に抑えられます。
他スクリプトとの統合による運用最適化
サービス制御スクリプトは、それ単体でも完結していますが、他のツールやスクリプトと組み合わせることで、より高い柔軟性と自動化を実現できます。
例えば、開発サーバーを初期化するinit_rhel_devhost.shや、アプリケーションレイヤーを構築するinstall_apache_host.shなどの前処理に、manage_service.shを組み込むことで、構築からサービス起動までの流れをシームレスに統一できます。
連携スクリプト | 組み込み目的 | 連携ポイント |
---|---|---|
init_rhel_devhost.sh | 初期セットアップ後のサービス起動 | ネットワーク・NTP設定後にchronyd起動 |
install_apache_host.sh | Apacheインストール完了後の起動 | httpd有効化とサービス状態チェック |
custom_backup.sh | バックアップ前のサービス停止 | データベースサービスの事前停止処理 |
このように、manage_service.shを基盤とした運用設計にすることで、スクリプト間の構成ルールが揃い、運用コストを抑えつつ柔軟な対応が可能になります。
まとめと今後の展開
本記事では、RHEL系Linux環境において任意のsystemdサービスを簡単に制御できる汎用スクリプト「manage_service.sh」の概要と活用方法について解説しました。サービスごとに異なる操作方法を意識することなく、共通の構文で起動・停止・再起動・状態確認ができる点は、日々の運用作業において大きなメリットとなります。今後もこのスクリプトをベースにした運用の標準化と、他ツールとの統合を進めていく予定です。
サービス制御の標準化に向けた第一歩
manage_service.shは、サービス名とコマンドの指定を明確化することで、運用者間の認識齟齬や記述ミスを減らし、共通の手順での操作を実現するための第一歩といえます。systemctlに対する直接操作を減らし、構造化されたシェルスクリプトを経由することで、ログの取得、通知処理、リトライ制御など、今後の高度な機能拡張に向けた土台も整います。
特に複数人で共有する開発・検証環境では、スクリプトを通じて統一されたオペレーションを実施することが、トラブル発生時の対応スピードにも直結します。システム管理における「属人化の排除」にも有効です。
他のShellスクリプトとの連携展望
すでに紹介している通り、manage_service.shはinitスクリプトやミドルウェアインストールスクリプトと組み合わせることで、構築から稼働までの一連の流れを自動化できます。今後は、以下のような処理との連携も視野に入れています。
連携先 | 目的 | 統合ポイント |
---|---|---|
firewalld設定スクリプト | サービス起動前にポートを開放 | ポート制御後に対象サービスを起動 |
証明書更新スクリプト | Let's Encrypt証明書の更新 | httpd再起動を安全に実行 |
バックアップ制御スクリプト | DBサービスの停止と起動制御 | 停止後にバックアップ処理を実行 |
これらのように、サービス制御処理をあらかじめ汎用スクリプトとして分離しておくことで、他の処理との境界が明確になり、構成の見通しも良くなります。
継続的なメンテナンスとスクリプト進化
このスクリプトは現時点での運用要件を満たすためのベースとして公開していますが、今後の運用フェーズや現場の課題に応じて柔軟に拡張・改善していく方針です。たとえば、次のような機能追加を検討しています。
機能 | 目的 | 想定方式 |
---|---|---|
サービス依存関係の定義 | 順序付き制御 | 設定ファイルを読み込んで連続実行 |
通知機能(Slack連携など) | 停止や異常の通知 | logOutフックを通じて通知APIを呼び出す |
リトライ機能 | 再起動失敗時の再実行 | exitLogで再評価処理を追加 |
このように、manage_service.shはあくまで運用現場に寄り添う実用的なツールとして成長させていく予定です。今後の記事でも、連携スクリプトや応用例の拡張について随時紹介していきます。