🐧

Pythonのプログラムをマシンの起動時に毎回実行させる方法

2023/11/03に公開

何がしたいか

PythonでDiscord Botを動かすためのプログラムを書いてRaspberry Piで実行しているのだが,再起動ごとに手動でプログラムを実行しないといけず運用がめんどくさい.そのためマシンが起動する度に自動でプログラムを実行するようにしたい.

今回使用する方法

/etc/rc.localやcrontabなどプログラムを自動で実行させる方法はいくつか存在するが,今回はsystemdを使用する.systemdの説明は割愛する.

環境

$ cat /etc/os-release 
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

手順

スクリプトの準備

今回自動実行させたいPythonのプログラムは/home/sora/ochakumi_manager/msg_reference.pyである(基本的に絶対パスで書く).以下にmanager.shを示す(任意のディレクトリで作成).

#!/usr/bin/env bash

# エラーが起きた時にスクリプトの実行を停止
set -o errexit
# 設定されていない変数をエラーとして扱う(今回あまり意味はない)
set -o nounset
# パイプの一部が失敗したらパイプ全体の失敗とみなす(今回あまり意味はない)
set -o pipefail

# 仮想環境のPythonを使用
/home/sora/ochakumi_manager/venv/bin/python /home/sora/ochakumi_manager/msg_reference.py

serviceファイルの作成(systemdのユニットの定義)

以下のようなmanager.serviceを任意のディレクトリに作成する.先ほど作成したシェルスクリプトの絶対パスが必要となる(今回は/home/sora/manager.sh).

[Unit]
Description=Discrod Bot

[Service]
ExecStart=/home/sora/manager.sh

[Install]
WantedBy=default.target

ユニットファイルを指定のディレクトリにコピー

以下のコマンドで/etc/systemd/systemに先ほど作成したユニットファイルをコピーする.

 sudo cp manager.service /etc/systemd/system

以下のコマンドを打って,systemdが認識したか確認する.

systemctl status manager.service

正しく認識されていると以下のような出力が得られる(この時点では動作していない).

$ systemctl status manager.service
○ manager.service - Discrod Bot
     Loaded: loaded (/etc/systemd/system/manager.service; disabled; vendor preset: enabled)
     Active: inactive (dead)

自動起動の設定

以下のコマンドを実行するだけ

sudo systemctl enable manager.service

以下のような出力が得られれば問題ない.

$ sudo systemctl enable manager.service
Created symlink /etc/systemd/system/default.target.wants/manager.service → /etc/systemd/system/manager.service.

試しに再起動(sudo reboot)をかけてみる.

$ systemctl status manager.service
● manager.service - Discrod Bot
     Loaded: loaded (/etc/systemd/system/manager.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2023-11-03 12:52:46 JST; 2min 53s ago
   Main PID: 679 (bash)
      Tasks: 4 (limit: 961)
     Memory: 33.0M
        CPU: 4.506s
     CGroup: /system.slice/manager.service
             ├─679 bash /home/sora/manager.sh
             └─699 /home/sora/ochakumi_manager/venv/bin/python /home/sora/ochakumi_manager/msg_reference.py

Nov 03 12:52:46 rpi3bp1 systemd[1]: Started Discrod Bot.
Nov 03 12:52:53 rpi3bp1 manager.sh[699]: [2023-11-03 12:52:53] [INFO    ] discord.client: logging in using static token
Nov 03 12:52:54 rpi3bp1 manager.sh[699]: [2023-11-03 12:52:54] [INFO    ] discord.gateway: Shard ID None has connected

正しく動作していることを確認した.

参考文献

  1. Michael Hausenblas著,武内覚ほか訳.入門 モダンLinux.オライリー・ジャパン,2023.
  2. Systemdで起動時にスクリプトを実行する(参照日:2023-11-03)
  3. systemd入門(参照日:2023-11-03)

Discussion