Hisakeyのブログ

エンジニアが色々呟くブログです。

ラズパイで理解する systemd とは 〜起動時に Python スクリプトを自動実行する〜

はじめに

この記事では、Raspberry Pi(ラズパイ)などの Linux 環境で、電源ON時に Python スクリプトを自動実行する方法を紹介します。

Linux には cron などの自動実行手段がありますが、「起動時に一度だけ実行したい」といった用途には systemd が使えるのかなと思い、

今回の記事にしてみました。

背景・動機

Raspberry Pi を使った自作プロジェクトで、起動と同時にスクリプトを自動実行したい場面がありました。

例えば、

毎回ターミナルを開いて手動でスクリプトを起動するのが面倒

電源を入れた瞬間からログ取得やデータ記録を始めたい

といったニーズです。

実例・やってみたこと

まず、systemdとは?

systemd は Linux における 起動プロセスの管理システムです。

systemctl コマンドでサービスの開始・停止・自動起動の設定などができます。

.service ファイルを作成して登録することで、 スクリプトを電源ON時に自動で実行できます。

実際に設定する

.serviceファイルを用意

説明はコメントを参照ください

[Unit]
Description=Run my script once at boot
After=network.target // ネットワーク起動後にスクリプトを実行する

[Service]
ExecStart=/user/bin/python3 /home/user/my_project/run_once.py //  スクリプトファイル
WorkingDirectory=/home/user/my_project  // スクリプト実行する作業ディレクトリ
StandardOutput=append:/home/user/log.txt
StandardError=append:/home/user/error_log.txt
Restart=no // 失敗後は再実行しない

[Install]
WantedBy=multi-user.target // 通常の起動状態時

仮想環境の場合は、ExecStart=/user/bin/python3 /home/user/my_project/run_once.pyの箇所で

/user/bin/python3が、/home/use/venv/bin/pythonのような指定となります。

shを登録

下記を実行することで、電源ONするたびにpythonスクリプトが実行されます。

#!/bin/bash

SERVICE_NAME="my_runner.service"

sudo cp $SERVICE_NAME /etc/systemd/system/
sudo systemctl daemon-reexec
sudo systemctl enable $SERVICE_NAME
sudo systemctl start $SERVICE_NAME

実行確認

systemctl status my_runner.service // 状態確認

tail -f /home/user/log.txt // ログ確認

学び・気付き

  • systemd は cron より柔軟かつ確実にスクリプトを起動してくれる
  • .service ファイル内で WorkingDirectory を明示しておかないと、相対パスがうまく動作しない

まとめ

  • systemd を使えば、ラズパイの電源ONと同時にスクリプトを確実に自動実行できる
  • cron に比べて 起動順序や依存関係を細かく制御できるのが大きな利点
  • .service ファイルの基本さえ押さえれば、比較的シンプルに使える