1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

新人エンジニアは「デーモン」がわからない ~ 2. systemd?なにそれ怖い~

Last updated at Posted at 2025-04-22

はじめに

前回、デーモンの基本について勉強する過程において今まで「systemd」とか言うやつを見て見ぬ振りをしていたことに気づきました。
なので今回でこの systemd にある程度の決着をつけようと思います。
そもそもの出発点はデーモンについて理解することなので、systemd で自作スクリプトを Linux のサービス(=デーモン)として登録・起動・管理することを目標にしてみようと思います。
…ハァ〜、だっる。

ゴール

自作スクリプトを systemd 経由でサービス(本物のデーモン)として起動・停止できるようにする。

全体の流れ

  1. 動かしたいスクリプトを用意
  2. systemdのサービス定義ファイルを作る
  3. systemdに登録する
  4. 起動&停止できるか確認

① サンプルスクリプトの作成

/home/youruser/logtime.sh (※自分のホームに置いてOK)

#!/bin/bash
# 毎分、現在時刻をログに記録する簡単なスクリプト
LOGFILE="/tmp/logtime_daemon.log"

while true; do
  echo "$(date): Hello from systemd daemon!" >> "$LOGFILE"
  sleep 60
done

実行権限を付けておく
chmod +x /home/youruser/logtime.sh

② systemd ユニットファイルの作成

/etc/systemd/system/logtime.service を作成します(管理者権限が必要)

sudo nano /etc/systemd/system/logtime.service

# サービスの説明や起動順序の定義
[Unit]
Description=Logtime Daemon
After=network.target

# サービスそのものの設定(どう実行するか)
[Service]
ExecStart=/home/youruser/logtime.sh
Restart=always
User=youruser
Group=youruser

# サービスの自動起動設定
[Install]
WantedBy=multi-user.target
# sudo systemctl enable logtime.service とすると以下のようなシンボリックリンクが作成される
# /etc/systemd/system/multi-user.target.wants/logtime.service → /etc/systemd/system/logtime.service
  • [Unit]
    • Description:サービスの説明
    • After:このサービスはネットワークが有効になった後で起動される
  • [Service]
    • ExecStart:実行するスクリプトを指定する
    • Restart=always:スクリプトが落ちても自動再起動する設定
    • User:サービスをこのユーザ権限で実行する
    • Group:実行時に使用するグループ
  • [Install]
    • WantedBy:systemctl enableで自動起動設定をONにした時に有効化される起動ターゲット
      • multi-user.target:CUI によるログインで、複数のユーザが同時にログイン可能な、サーバ向けの標準的な起動状態のこと
      • graphical.target:GUI によるログインで、複数のユーザがログイン可能な、デスクトップ向けの標準的な起動状態のこと
      • rescue.target:レスキューモード(最小限の回復)

【ちょっと脱線】 .service ってなに?これも拡張子なの?

そうらしいです。他にも色々あります。

主なユニットファイルの種類と拡張子

拡張子 意味 役割の例
.service サービス 常駐プロセス(デーモン)を定義する
.timer タイマー 特定の時刻や間隔で .service を起動する
.socket ソケット ポート待ち受けで .service を起動する
.mount マウント ファイルシステムのマウント設定
.target ターゲット 複数サービスの起動順序を制御する
.path ファイル監視 特定ファイルやディレクトリの変化を検知して .service を起動する

!! [todo] device, swap もある

なぜ拡張子が必要なの?

systemctl は、拡張子がないとどの種類のユニットを扱うのか分からないからです。

たとえば、以下の systemctl startコマンドは今すぐ logtime.service を探して実行しますが、.service を省略して実行することもできます。

sudo systemctl start logtime

でもタイマー(timer)の場合は、以下のように .timer 付きで指定する必要があります。
(enableは、起動時に自動起動をONにするコマンド(すぐには実行されない))

sudo systemctl enable logtime.timer

各ユニットファイルの超簡単な例

ここでは先ほどの logtime.service を中心に、以下の systemd ユニットタイプ(.timer, .socket, .mount, .target, .path)を実用に近い超簡単な例で紹介します。
(このサービスは /home/youruser/logtime.sh を実行して、1分ごとにログを出すだけの簡単なデーモンです。)

.timer : 定期実行したいとき
# /etc/systemd/system/logtime.timer
[Unit]
Description=Run logtime every minute

[Timer]
OnBootSec=30sec         # 起動から30秒後に最初の実行
OnUnitActiveSec=1min    # その後、毎分実行
Unit=logtime.service    # 起動対象のサービス

[Install]
# 有効化(enable)した時に「timers.target.wants/」にシンボリックリンクで紐づける指定
# (/etc/systemd/system/timers.target.wants/logtime.timer => /etc/systemd/system/logtime.timer)
WantedBy=timers.target 

sudo systemctl enable --now logtime.timer

📝 .timer は .service をスケジュールで起動するためのトリガーです。logtime.service を毎分起動→終了させる場合に使えます。

処理の流れ:

logtime.timer
↓(時間になったら)
logtime.service
↓(サービスとして起動)
logtime.sh

.socket : 接続されたら起動する

これは少し特殊ですが、たとえば「ポート12345に接続があったら logtime.service を起動する」ように設定できます。

# /etc/systemd/system/logtime.socket
[Unit]
Description=Socket for logtime

[Socket]
ListenStream=12345
Accept=no

[Install]
# /etc/systemd/system/sockets.target.wants/logtime.socket => /etc/systemd/system/logtime.socket
WantedBy=sockets.target

そして .service 側も対応が必要

# logtime.service(例)
[Service]
ExecStart=/home/youruser/logtime.sh
StandardInput=socket

sudo systemctl enable --now logtime.socket

📝 .socket は ソケット接続をトリガーに .service を起動します。

.mount : マウントポイントを定義する

たとえば /mnt/myusb に /dev/sdb1 を自動マウントしたい場合

# /etc/systemd/system/mnt-myusb.mount
[Unit]
Description=Mount USB drive

[Mount]
What=/dev/sdb1
Where=/mnt/myusb
Type=auto

[Install]
WantedBy=multi-user.target

sudo mkdir -p /mnt/myusb
sudo systemctl enable --now mnt-myusb.mount

※ ファイル名のルール:/mnt/myusb → mnt-myusb.mount

.target : 一括起動やグループ化

自作の .target に複数の .service を紐づけることができます。

# /etc/systemd/system/logbundle.target
[Unit]
Description=My custom log target

そして、logtime.service に以下を追加

[Install]
# /etc/systemd/system/logbundle.target.wants/logtime.service => /etc/systemd/system/logtime.service
WantedBy=logbundle.target

sudo systemctl enable logtime.service
sudo systemctl start logbundle.target

.target は複数ユニットの**グループ(起動単位)**として使えます。

.path : ファイルやディレクトリの変化を監視

たとえば /tmp/start_trigger.txt が作られたら logtime.service を起動したい。

# /etc/systemd/system/logtime.path
[Unit]
Description=Watch trigger file

[Path]
PathExists=/tmp/start_trigger.txt
Unit=logtime.service

[Install]
WantedBy=multi-user.target

sudo systemctl enable --now logtime.path

.path は ファイル・ディレクトリの監視 → 自動実行 を可能にします。

まとめ

ユニットタイプ 用途 logtimeとの例
.service 実行本体 logtime.sh を動かす
.timer 定期実行 毎分自動で実行
.socket ポート接続で起動 接続時に実行(非同期)
.mount デバイスマウント USBやHDD自動マウント
.target グループ起動 複数サービスまとめ起動
.path ファイル監視 特定ファイル作成で起動

③ systemd にサービスを読み込ませる

sudo systemctl daemon-reexec
sudo systemctl daemon-reload

④ サービスを起動・自動起動に登録!

sudo systemctl start logtime.service
sudo systemctl enable logtime.service # 再起動後も自動起動させる場合

動作確認

sudo systemctl status logtime.service

動いていれば、/tmp/logtime_daemon.log に1分ごとにログが追加されていきます。

停止する場合

sudo systemctl stop logtime.service

削除したい場合

sudo systemctl disable logtime.service
sudo rm /etc/systemd/system/logtime.service
sudo systemctl daemon-reload

まとめ

操作 コマンド例
起動 sudo systemctl start logtime.service
停止 sudo systemctl stop logtime.service
自動起動ON sudo systemctl enable logtime.service
ステータス確認 sudo systemctl status logtime.service

補足

  • 実際の業務では Python で書かれたデーモンを systemd で管理することが多いです
  • ログ出力は journald 経由にすることも可能です(StandardOutput=journal など)

終わりに

まあわかった部分もあれば、むしろわからない部分が増えた感じですねー。
とりあえず、次に python でデーモンを作ることができたらとりあえずは良しとします。
そのうちまた必要になったら勉強しますね。今はもう、さっさとこの勉強を終わらせたいっす。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?