2021年07月30日 更新

systemdを使ってスクリプト自動起動

どうも、クラゲです。
systemdを使って、ラズパイが起動したときに指定したスクリプトを自動的に実行させる方法です。今回は起動時に毎回効果音を鳴らすというスクリプト例で作成してみます。

目次

[TOC]

様々な方法

起動時の実行として以下のようなものがあります。

  • rc.local
  • autostart
  • systemd

rc.local

以下のファイルに追記する方法。OS起動時に実行されます。

/etc/rc.local

exit 0 より上の行に記述します。

autostart

以下のファイルに追記する方法。GUIが立ち上がってから実行されます。

~/.config/lxsession/LXDE-pi/autostart

具体的に記述する内容は@を付けるのが特徴的です。

systemd

上記の2つは非常に簡単に扱えて良かったのですが、古い方法のため、そのうちサポートされなくなる可能性があります。
今回説明する systemd は Raspbian Jessie から推奨されている自動起動方法ですが、上記の2つに比べて必要なステップが多いので、順に見てゆきましょう。

systemd自動起動の作成ステップ

ステップは大きく3つです。

  • スクリプトファイル作成
  • サービスファイル作成
  • サービス有効化

スクリプトファイル作成

起動時に実行させたいスクリプトを作成します。今回は効果音を鳴らすという例です。
フォルダ作成と効果音を用意し、最後にPythonスクリプトを作成します。

フォルダ作成

まずスクリプトファイルを置くフォルダを作ります。 /home/pi/myapp にしましたが、場所も名前も自由に決められます。

mkdir /home/pi/myapp
cd /home/pi/myapp

効果音準備

ラズパイにデフォルトで入っているwavファイルを利用します。
/usr/share/sounds/alsa というフォルダにいくつか音声ファイルが入っているので、今回は Front_Center.wav をコピーして活用します。

cp /usr/share/sounds/alsa/Front_Center.wav /home/pi/myapp/start.wav

音声ファイルをコピーして /home/pi/myapp フォルダに入れて、ファイル名を start.wav にしています。
上記コマンドがうまくいかなかったり、他の音を使いたい人は、自分で好きに準備してもらってOKです。ちなみに、ウェブ上で「効果音 wav」などで検索するとすぐに見つかります。

Pythonコード

同じフォルダ内に以下の内容で start_app.py というスクリプトファイルを作成します。以下はテキストエディッタnanoを使って書く場合のコマンドです

nano /home/pi/myapp/start_app.py

aplayコマンドで start.wav を再生するだけのスクリプトです。

import subprocess
subprocess.run(['aplay', 'start.wav'])

nanoは Ctrl + O Enter で保存し、 Ctrl + X で終了します。

サービスファイル作成

/etc/systemd/system の下にサービスファイルを作成します。

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

書く内容は以下の通りです。

[Unit]
Description=Play sound effects at startup
After=network.target

[Service]
ExecStart=/usr/bin/python3 start_app.py
WorkingDirectory=/home/pi/myapp

[Install]
WantedBy=multi-user.target

[Unit] [Service] [Install] の3つを書きます。それぞれの中身を簡単に説明します。

Unit

Description= の後の文字列はスクリプトの説明メモです。任意の文字列を書けます。
After=network.target を書くことでインターネット接続を待ってから処理が始まります。

Service

ExecStart= の後に実行させたい内容を書きます。今回はPython3でstart_app.pyを実行しています。
WorkingDirectory= の後にスクリプトファイルのディレクトリを書きます。これを書くことで、ExecStart での記述が相対パスで良いだけでなく、スクリプトファイルの中身も相対パスのままでOKとなるので絶対おすすめ。
スクリプトが無限ループなどの場合は、別の行に Restart=always を書いておくことで、異常終了したときにスクリプトを再起動させることができます。ただし、今回の例のように効果音を出して終了するスクリプトの場合は、何度も起動してしまうので注意してください。

Install

WantedBy=multi-user.target は、必須の記述。
multi-user.targetが起動する、つまりCUI環境が起動したときにスクリプトを実行させます。ちなみにGUI環境の起動時で良ければ、graphical.target にします。

サービス有効化

サービスファイルを作るだけではダメで、有効にする必要があります。
それが以下のコマンドです。

sudo systemctl enable start_app.service

これで完了! ラズパイを再起動すれば実行されるようになります。

その他

サービス無効化

以下のコマンドで無効化できます。
再び有効化させたい場合は先程のサービス有効化コマンドだけでOK

sudo systemctl disable start_app.service

トラブルシューティング

  • サービスファイルを編集した場合は systemctl daemon-reload と打つ
  • Pythonスクリプトで subprocess.Popen が実行されない場合があるので subprocess.run に変えてみる
  • 状態やログ確認は systemctl status start_app.service と打ち込む。Ctrl + Cで終了。

参考にさせていただいたサイト

https://www.raspberrypi.org/documentation/linux/usage/systemd.md

以上、「systemdを使ってスクリプト自動起動」でした!