systemdを使ったプログラム自動起動

自分の作製したプログラムをRaspberry PI 起動時に自動実行させる方法は幾つか有りますが今回はsystemdを使用する方法に付いて説明します。systemdに付いて簡単に言うと

ーーー Raspberry PIを起動する為の多くのプログラムの実行順を管理するアプリ。ーーー

って感じでしょうか。例えは大げさですが自分で作ったプログラムもRaspberry PIを起動するのに必要なプログラムとして考えれば、systemdを使って起動と共に実行させる事も出来る訳です。

プログラム実行順確認

Raspbarry PIのモニターで、$ systemd-analyze plot > unitstart.html と実行すると下記の様なファイルが作成されます。これは、上から下に向かってRaspberry PIが立ち上がるまでに実行されたプログラムの実行履歴です。

事前の調べで、自作のプログラムを自動起動させるなら特別な理由が無い限り、”multi-user.target”の後が良いと有ったので、”multi-user.target” を探すと殆ど終わりの方に有りました。(下記も矢印の位置)確かにこの位置なら自作のプログラムが実行されても問題無いと思います。

実行するには設定ファイルが必要

Systemdはユニット単位で実行されます。自動起動させたいプログラムがどのユニットに属するかで作成するファイルの拡張子が変わって来ます。今回起動したいプログラムはネットラジオで、この類のプログラムはサービスユニットになります。サービスユニットの場合はファイルの拡張子は ”.service” 。また今回自動実行したいプログラムは

  • ファイル種類: Python3プログラム。 radio.py
  • Path:      /home/pi/radio
  • 作業フォルダ: /home/pi/radio

とします。

作成するファイル名は、”radio_run.service”。保存する場所は、/etc/systemd/system/ 。ファイルの内容は以下の通り。


[Unit]
Description=Net Radio
After=multi-user.target

[Service]
ExecStartPre=pulseaudio --start
ExecStart=/usr/bin/python3  radio.py
WorkingDirectory=/home/pi/radio
Restart=always
User=pi

[Install]
WantedBy=multi-user.target
  • [Unit] : プロセスの説明や依存関係、起動順序などを設定する。
    • Description=Net Radio
      • プログラムの説明。特に規定は無い模様。
      • プログラムの名前、”Net Radio” を入れました。
    • After=multi-user.target
      • プログラムの実行位置を指定する方法の1つ。
      • ここで指定したサービス、”multi-user.target” の後に今回のプログラムが実行される。
  • [Service]: 起動させたいプログラムや作業ディレクトリ等の指定を行う。
    • ExecStartPre=pulseaudio –start
      • 本来実行するプログラムの前に実行させたいプログラムを指定。
      • 今回は、オーディオアプリ、Pulseaudioを実行しています。
    • ExecStart=/usr/bin/python3 radio.py
      • ここに実行したいプログラムを指定します。
      • Python Script、”radio.py” をPython3で実行となります。
    • WorkingDirectory=/home/pi/radio
      • このプログラムは、/home/pi/radioを作業フォルダにする必要があり、ここで指定しています。
    • Restart=always
      • サービスプロセス停止時の再起動条件の設定。これでRestart出来る様になります。
    • User=pi
      • 実行するユーザー指定
  • [Install]:サービスに依存するユニットを指定
    • WantedBy=multi-user.target
      • 今回はCUIで実行するので、”multi-user.target”を指定。

この他にも多くのパラメータが有ります。”systemdによる自動起動“ に詳しい説明が有ります。参照下さい。

サービス(プログラム)の起動/停止

下記コマンドで上記で作成したサービスを起動/停止することができます。


$ sudo systemctl start radio_run.service  <--- サービスを起動するコマンド
$ sudo systemctl stop radio_run.service  <--- サービスを停止するコマンド

先ずは、ターミナルで、 sudo systemctl start radio_run.service を実行。何もメッセージが帰って来なければ、起動したはずです。続けて sudo systemctl status radio_run.service を実行した結果が下記です。

上の方に、● radio_run.service – Net Radioとあり、状態は:active (running)。PIDは1206(python3)と有ります。PSコマンドで確認すると、

PID 1206にPython3が有ることが確認出来ます。Statusの画面の下の方に赤くFailedと有りますが、プログラム自体は問題無く動いています。

次に、sudo systemctl stop radio_run.service を実行。sudo systemctl status radio_run.serviceで状態が:inactive(dead)になっている事を確認。PSコマンドにも表示されていない事が分かります。

もう一度、sudo systemctl start radio_run.service を実行して、radio_run を起動させ、systemd-analyze plot > unitstart.htmlで予定通り、”multi-user-target”の後に、”radio_run.service”が入っているか確認すると、入っていません。当然ですよね。systemd-analyze plot > unitstart.html は起動時実行したプログラムの履歴ですから、起動した後に、”radio_run.service”を起動しても予定した場所に入るはずは有りません。

ここまで来れば後は登録のみ

起動時に実行または実行を停止させるには、下記のコマンドを使用します。


$ sudo systemctl enable radio_run.service  <--- サービスを自動で起動させる
$ sudo systemctl disable radio_run.service  <--- サービスを自動で起動させない

ターミナルで、sudo systemctl enable radio_run.service と入力して、Raspberry PIをReboot。

Reboot後、sudo systemctl is-active radio_run.service で ”radio_run.service” の起動を確認すると、active(起動)と帰って来ます。

ここで、systemd-analyze plot > unitstart.html を実行すると、”multi-user-target”の後に、”radio_run.service”が入っている事が確認出来ます。もちろんプログラムも実行しています。(ラジオが聞けます)

最後に

これで、systemdを使ったプログラムの自動起動の説明を終わります。設定ファイルの作り方がキーですね。