【问题标题】:Restart command for Discord.pyDiscord.py 的重启命令
【发布时间】:2021-07-19 09:24:36
【问题描述】:

这段代码:

await Bot.close()

用于注销Bot。
问题是我想写一个重启命令,像这样:

@Bot.command()
async def OFF(ctx, seconds:float):
    await ctx.message.delete()
    embed = Embed(title = "OFF", description = f"{ctx.message.author.mention} turned off me for {round(seconds)} seconds", color = Color.red())
    await ctx.send(embed = embed)
    await Bot.close()
    await sleep(seconds)
    await Bot.login(token)
    embed = Embed(title = "Turned on", description = f"I came back after {round(seconds)}", color = Color.green())
    await ctx.send(embed = embed)

问题是当 Bot 关闭时,必须重新启动 shell,否则程序在 {seconds}sec 后将无法继续运行。

如何创建一个重新启动 Bot 的命令?
提前致谢

【问题讨论】:

  • await sleep() 已过时,您宁愿使用asyncio.sleep()。您是否看过其他也涉及重新启动机器人的帖子? StackOverflow 上有大量示例。
  • 是的,我看了其他帖子,没有人回答我的问题。
  • (@Dominik,我在程序开始时做了“从时间导入睡眠”)

标签: python-3.x discord.py


【解决方案1】:

所以您应该能够在不关闭终端的情况下断开连接然后重新连接。

请注意,我使用的是 .connect() 而不是 .login(),因为当您关闭连接时,您实际上并没有退出不和谐。

编辑:我没有注意到,但 Dominik 提到睡眠不是异步的,因此您可以通过导入 asyncio 并使用 await asyncio.sleep(seconds) 或仅使用 time.sleep 函数使其异步(尽管它不必要)你是,但没有等待。

@Bot.command()
async def OFF(ctx, seconds:float):
    await ctx.message.delete()
    embed = Embed(title = "OFF", description = f"{ctx.message.author.mention} turned off me for {round(seconds)} seconds", color = Color.red())
    await ctx.send(embed = embed)
    await Bot.close()
    sleep(seconds)
    await Bot.connect()
    embed = Embed(title = "Turned on", description = f"I came back after {round(seconds)}", color = Color.green())
    await ctx.send(embed = embed)

【讨论】:

  • 这不起作用。在 Bot.close() 调用 shell 结束后,我遇到了和以前一样的问题。
  • 尝试在 cmd 中使用python bot_file.py 运行脚本。并告诉我在使用该命令时是否出现任何错误。
  • 没有出现错误,但在 Bot.close() 调用 .exe 文件后简单地关闭
【解决方案2】:

您可以使用os.execv() function 完全重启您的机器人。

"[...] 执行[s] 一个新程序,替换当前进程;[it does] 不返回"


实现是

os.execv("path-to-python-bin", ["python"] + ["absolute-path-to-bot-main-file"])

例如

os.execv("/usr/local/bin/python3.8", ["python"] + ["/home/user/test/bot.py"])

你的命令可以这样实现

@Bot.command()
async def OFF(ctx, seconds:float):
    await ctx.message.delete()
    embed = Embed(title = "OFF", description = f"{ctx.message.author.mention} turned off me for {round(seconds)} seconds", color = Color.red())
    await ctx.send(embed = embed)
    os.execv("path-to-python-bin", ["python"] + ["absolute-path-to-bot-main-file"])

Discord.py 将为您处理所有注销和重新登录。无需单独调用函数。

【讨论】:

  • 这根本不实用,它重新启动了整个脚本,而不是机器人,并且牺牲了效率,因为机器人必须重新登录。我建议使用 discord.py 解决方案.
  • 这是个坏主意,os.exec* 会因为不让旧进程死掉而耗尽你的记忆。 OP 应该在进程管理器中运行机器人并让它处理机器人重启。
  • @Judev1,我知道,您对 Discord.py 解决方案有什么建议吗?
【解决方案3】:
import sys
def restart_bot(): 
  os.execv(sys.executable, ['python'] + sys.argv)

@bot.command(name= 'restart')
async def restart(ctx):
  await ctx.send("Restarting bot...")
  restart_bot()

这将完美无缺。您的代码不起作用,因为一旦使用 bot.close 停止机器人,它就无法自动打开

【讨论】:

  • @Judev1 这适用于您的命令。至少它不适合我
猜你喜欢
  • 2021-06-15
  • 1970-01-01
  • 2020-10-19
  • 2021-07-15
  • 2020-12-31
  • 2021-03-26
  • 2019-10-23
  • 2020-05-03
  • 2020-11-06
相关资源
最近更新 更多