Shellの基礎知識(実践編)

【RHEL系Linux】任意サービスを簡単制御!汎用サービススクリプトの活用術

RHEL系Linuxで複数のサービスを管理していると、systemctlコマンドによる起動・停止の操作を何度も繰り返す場面が出てきます。Apache(httpd)やSSH、chronyd、PostgreSQLなど、制御対象が増えるほど入力作業が煩雑になり、運用ミスや確認漏れの原因にもなります。

今回紹介する「サービス制御スクリプト(manage_service.sh)」は、そんな日常の繰り返し作業を一元化・簡略化するために開発した汎用スクリプトです。-s でサービス名、-c で操作コマンドを指定するだけで、systemd管理下の任意サービスを柔軟に制御できます。

サーバーごとに異なるサービスを一括で管理したい方、自作スクリプトや自動化ツールに組み込みたい方に最適な構成です。

運用自動化ツール

🟡 運用自動化ツール
📌 面倒な作業を一括効率化!シェルスクリプトで実現する運用自動化術
├─ 基本共通
| ├─【Shellの基礎知識】簡単なログ出力ロジックを作ってみました。
| ├─【Shellの基礎知識】シェルスクリプトの作成を時短!テンプレートで効率化する方法
| ├─【Shellの基礎知識】共通関数定義クラスの完全ガイド!設計から実践まで徹底解説
├─ 開発環境構築
| ├─【RHEL系Linux】開発サーバー初期設定スクリプトの完全自動化
| ├─【RHEL系Linux】Apache+Let's Encrypt 自動構築スクリプト|バーチャルホスト対応
| ├─【RHEL系Linux】Tomcatを自動インストール・設定するスクリプトの作成と活用法
| └─【RHEL系Linux】PostgreSQLを自動インストールするシェルスクリプトの使い方
└─ 運用・保守
  ├─【RHEL系Linux】任意サービスを簡単制御!汎用サービススクリプトの活用術
  ├─【RHEL系Linux】ファイルやログを自動圧縮する汎用スクリプトの実装と活用法
  ├─【RHEL系Linux】リソース(CPU・MEM)監視スクリプトで使用率・異常を検知する仕組み
  ├─【RHEL系Linux】中間ファイル連携を完全制御するファイル転送スクリプト
  ├─【RHEL系Linux】信頼性を重視した完了保証型ディレクトリ転送スクリプトの設計と実装
  ├─【RHEL系Linux】ディスク使用率を自動監視するシェルスクリプトの実装
  └─【RHEL系Linux】サーバーの障害検知と自動通知|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(レポート出力領域)

サービス制御スクリプト

サービス制御スクリプト(manage_service.sh)の全文を以下に掲載します。このスクリプトは、systemctlで管理されている任意のサービスに対して、起動・停止・再起動・状態確認・graceful再読み込みといった操作を安全に実行できるよう設計されています。

#!/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.shApacheインストール完了後の起動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はあくまで運用現場に寄り添う実用的なツールとして成長させていく予定です。今後の記事でも、連携スクリプトや応用例の拡張について随時紹介していきます。

よく読まれている記事

1

「私たちが日々利用しているスマートフォンやインターネット、そしてスーパーコンピュータやクラウドサービス――これらの多くがLinuxの力で動いていることをご存じですか? 無料で使えるだけでなく、高い柔軟 ...

2

Linux環境でよく目にする「Vim」という名前。サーバーにログインしたら突然Vimが開いてしまい、「どうやって入力するの?」「保存や終了ができない!」と困った経験をした人も多いのではないでしょうか。 ...

3

ネットワーク技術は現代のITインフラにおいて不可欠な要素となっています。しかし、ネットワークを深く理解するためには、その基本となる「プロトコル」と「レイヤ」の概念をしっかり把握することが重要です。 こ ...

4

この記事は、Linuxについて勉強している初心者の方向けに「Shellスクリプト」について解説します。最後まで読んで頂けましたら、Shellスクリプトはどのような役割を担っているのか?を理解出来るよう ...

5

Javaは世界中で広く使われているプログラミング言語であり、特に業務システムやWebアプリケーションの開発において欠かせない存在です。本記事では、初心者向けにJavaの基礎知識を網羅し、環境構築から基 ...

-Shellの基礎知識(実践編)