0
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?

More than 1 year has passed since last update.

itohalAdvent Calendar 2022

Day 18

discord botをdaemonにする流れ

Posted at

前提

なぜかこの記事は準備編と別れています.前編はこちら

さて,私の環境は

  • WSL, Ubuntu22.04.1

となっています.他の環境だとどうなるかは正直わかりません.

daemonにする流れは以下を参考にしています.

discord botのプログラムにShebangを仕込む

とりあえずプログラムにShebangを仕込んで,実行権限を与えておきます.

defaultbot.py
#!/usr/bin/env python3
import discord
import os

class MyClient(discord.Client):
    def __init__(self, *, intents: discord.Intents):
        super().__init__(intents=intents)

    async def on_ready(self):
        print(f"Logged in as {client.user} (ID: {client.user.id})")
        print("------")


intents = discord.Intents.default()
client = MyClient(intents=intents)
client.run(os.getenv("TOKEN"))
bash
$ chmod +x defaultbot.py

続いて,daemonの設定ファイルであるUnitファイルを書いていきます

Unitファイル

pythonプログラムをデーモン化する|Unitに処理を記述しsystemdで実行するという記事を参考にしています.

testbot.serviceというUnitファイルを/etc/systemd/system/に作成し,daemonを作っていきます.

testbot.service
[Unit]
Description = test discord bot daemon

[Install]
WantedBy = multi-user.target

[Service]
EnvironmentFile = /home/user/directory/.env
ExecStart = /home/user/directory/defaultbot.py

[Service]のExecStartに実行したいファイルを絶対パスで指定します.また,環境変数を使用するので,それが書かれたファイルをEnvironmentFileに指定します1

multi-user.target

ちなみに,WantedByに指定したmulti-user.targetですが,OS起動時にsystemdで行われていることという記事によると,GUIなしのアプリ起動に紐づいたものらしいです.
蛇足ですが中身も一応見れます.まあ見ても私にはなにもわかんないんですけど

bash
$ systemctl cat multi-user.target
# /lib/systemd/system/multi-user.target
#  SPDX-License-Identifier: LGPL-2.1-or-later
#
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes

これで準備が整いました.準備編は終わったんじゃなかった?

次にdaemonとして認識させましょう.

systemctl

daemonとして認識されているか,および起動や停止,自動実行の設定にはsystemctlコマンドを利用します.
systemctlのコマンドの詳細については以下の記事を参考にしています.

まずはsystemctl list-unit-files --type serviceを使って認識されているか確認しましょう.
というところで,WSLだとおそらくsystemctlが使えねえっていうエラーが出ると思います.PID1にsystemdが設定されてないよ,というエラーです.これの解決方法はこちらの記事に載っています.WSLのUbuntu上の/etc/wsl.conf

[boot]
systemd=true

を記述し,WSLを再起動させるとできるようになります.wsl.confについてはこちらを見てください.
ただし,ここでWSLをシャットダウンさせて再起動させる際,8秒ほど待たないといけません.詳しくは公式のドキュメントを見てください.

というわけでこれでsystemctlが使えると思います.試してみてtestbot.serviceが表示されるか確認しましょう.

bash
$ systemctl list-unit-files --type service | grep testbot
testbot.service                            disabled        enabled

出てきましたね.次はこれを有効にしましょう.

bash
$ sudo systemctl enable testbot.service
Created symlink /etc/systemd/system/multi-user.target.wants/testbot.service → /etc/systemd/system/testbot.service.

できたら後は起動するだけです.

bash
$ sudo systemctl daemon-reload
$ sudo systemctl start testbot.service
$ sudo systemctl status testbot.service
● testbot.service - test discord bot daemon
     Loaded: loaded (/etc/systemd/system/testbot.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2022-12-18 00:40:04 JST; 18s ago
   Main PID: 1701 (python3)
      Tasks: 3 (limit: 9421)
     Memory: 22.8M
...

動きました.やったね.
停止するには,stopさせればいいです.

bash
$ sudo systemctl stop testbot.service
$ sudo systemctl status testbot.service
○ testbot.service - test discord bot daemon
     Loaded: loaded (/etc/systemd/system/testbot.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Sun 2022-12-18 00:41:48 JST; 3s ago
    Process: 1701 ExecStart=/home/......./defaultbot.py (code=killed, signal=TERM)
   Main PID: 1701 (code=killed, signal=TERM)

Dec 18 00:40:04 DESKTOP-CN6AQ4U systemd[1]: Started test discord bot daemon.
Dec 18 00:40:04 DESKTOP-CN6AQ4U defaultbot.py[1701]: [2022-12-18 00:40:04] [INFO    ] discord.client: logging in using static token
Dec 18 00:40:05 DESKTOP-CN6AQ4U defaultbot.py[1701]: [2022-12-18 00:40:05] [INFO    ] discord.gateway: Shard ID None has connected to Gateway (>
Dec 18 00:41:48 DESKTOP-CN6AQ4U systemd[1]: Stopping test discord bot daemon...
Dec 18 00:41:48 DESKTOP-CN6AQ4U systemd[1]: testbot.service: Deactivated successfully.
Dec 18 00:41:48 DESKTOP-CN6AQ4U systemd[1]: Stopped test discord bot daemon.

これでPCが起動しっぱなしであればdiscord botも起動しっぱなしになりました.

ちなみに蛇足ですが,私の環境だと,

$ explorer.exe .
run-detectors: unable to find an interpreter for /mnt/c/WINDOWS/explorer.exe

windowsのアプリがWSLでが使えなくなりました.

windowsのアプリがWSLで使えない

こちらに載っている解決方法を試したところ,

  • wsl --shutdownして再起動
    • 変わらず
  • export DISPLAY="$(/sbin/ip route | awk '/default/ { print $3 }'):0" to ~/.bashrc
    and‘ sourced it and $ source ~/.bashrc
  • sudo update-binfmts --disable cli
    • 上2つを同時に実行
    • 使えるようになったけど,再起動で再び使えなくなる
  • [interop]appendWindowsPath = trueにする
    • 変わらず

で変わりませんでした.[automount]の設定が怪しい気がしたので消してみましたが変わらずです.

解決策はwsl.conf[boot]systemd=trueを削除すると使えるようになります.本末転倒ですね.

調べた結果....わかりませんでした!
いかがでしたか?

以上となります.daemon起動の流れを紹介しました.

  1. itohalってやつが書いた環境変数の記事では.profileに環境変数を設定することができるらしいので,.profileに環境変数ファイルに指定して起動してみたらうまくいきませんでした.環境変数を認識してくれません.どうして.
    .bash_profileではうまくいきます.なんで.profileに環境変数を入れることをおすすめしてるんだ.
    ちなみに,.envで動くのかなと思って試してみたらうまくいったのでそうやってます.
    .env.bash_profile.profileの違いを考えたとき,性質の違いは置いておいて,exportかなと思います.前者ではtoken="000"と記述(.bash_profileではそこからexport token)して,.profileではexport token="000"としています.echoさせるとどちらもうまくいきますが,daemonだと前者がうまくいきます.なんでだろ

0
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
0
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?