如何打开终端并运行脚本,然后通过 discord bot 关闭它

Posted

技术标签:

【中文标题】如何打开终端并运行脚本,然后通过 discord bot 关闭它【英文标题】:How to open terminal and run script and then close it by discord bot 【发布时间】:2021-06-22 12:04:37 【问题描述】:

我正在尝试制作一个不和谐机器人来通过不和谐启动我的我的世界服务器。这就是我目前所拥有的。

import os
import discord
import subprocess

@client.event
async def on_message(message):
    if message.author == client.user:
        return
    if message.content == 'server!start':
        await message.channel.send('Loading ngrok...')
        #run terminal with ngrok
        await message.channel.send('Loading minecraft server...')
        #run terminal with minecraft server
    if message.content == 'server!stop':
        await message.channel.send('Stopping server...')
        #stop minecraft and ngrok by killing terminal

在代码中,我想打开终端并执行 bash 脚本来运行服务器,然后,当需要关闭它时,我想杀死终端或将“停止”发送到控制台。

编辑:我尝试使用 subprocess.Popen,但我无法从另一个 if 语句关闭它,而不是我第一次执行该语句

@client.event
async def on_message(message):
    if message.author == client.user:
        return
    if message.content == 'server!start':
        await message.channel.send('Loading ngrok...')
        ngrok = subprocess.Popen("/home/administrator/minecraft/server/startngrok.sh", shell=True)
        #run terminal with ngrok
        await message.channel.send('Loading minecraft server...')
        minecraft = subprocess.Popen("/home/administrator/minecraft/server/startserver.sh", shell=True)
        #run terminal with minecraft server
    if message.content == 'server!stop':
        await message.channel.send('Stopping server...')
        ngrok.terminate()
        server.terminate()
        #stop minecraft and ngrok by killing terminal
enter code here

这是输出:

Ignoring exception in on_message
Traceback (most recent call last):
  File "/home/administrator/.local/lib/python3.8/site-packages/discord/client.py", line 343, in _run_event
    await coro(*args, **kwargs)
  File "/home/administrator/minecraft/bot/bot.py", line 25, in on_message
    ngrok.terminate()
UnboundLocalError: local variable 'ngrok' referenced before assignment

【问题讨论】:

到目前为止您尝试过什么?您认为哪些选项会起作用? 好吧,我正在尝试使用 subprocess.Popen。它允许我打开终端并运行服务器,但我不能在另一个语句中终止它,而不是运行它们。 您似乎走在了正确的轨道上。您是否研究过如何终止子进程?这是一个好的开始How to terminate a subprocess in Python 请做你的研究并尝试实施它 我想我已经完成了与此站点类似的所有操作,但我无法终止它。我仍然收到错误消息。看看编辑。 这个错误是不言自明的。它基本上意味着在那个范围级别,它不知道ngrok 是什么。您应该修复您的范围,以便两个 if 语句都可以访问子流程对象 【参考方案1】:

当前错误:UnboundLocalError: local variable 'ngrok' referenced before assignment 这意味着在调用ngrok.terminate() 之前没有初始化(定义)'ngrok'。发生这种情况是因为您在上面的 if 条件中初始化了您的 ngrok,但是说,如果您从未运行过该条件怎么办?那么ngrok 将永远不会被定义为任何东西。你要做的是先初始化它。

import os
import discord
import subprocess

@client.event
async def on_message(message):
    # define 'ngrok' variable
    ngrok = null
    if message.author == client.user:
        return
    if message.content == 'server!start':
        await message.channel.send('Loading ngrok...')
        ngrok = subprocess.Popen("/home/administrator/minecraft/server/startngrok.sh", shell=True)
        #run terminal with ngrok
        await message.channel.send('Loading minecraft server...')
        minecraft = subprocess.Popen("/home/administrator/minecraft/server/startserver.sh", shell=True)
        #run terminal with minecraft server
    if message.content == 'server!stop':
        await message.channel.send('Stopping server...')
        # If 'ngrok' is a NoneType, catch it
        try:
            ngrok.terminate()
        except AttributeError:
            # exception message or desired except code
        server.terminate()
        #stop minecraft and ngrok by killing terminal

但是,我也没有在任何地方看到服务器定义。可能会出现更多错误。如果您需要更多帮助,请提供sample reproducible code。

【讨论】:

不,它不起作用。它一直在给我这个异常消息。我尝试定义 ngrokserver 本地和全局,但两个选项都不起作用(我使用 None 定义 null) 很难确定到底发生了什么。请提供重现代码的步骤。

以上是关于如何打开终端并运行脚本,然后通过 discord bot 关闭它的主要内容,如果未能解决你的问题,请参考以下文章

制作一个打开3个cygwin终端并执行命令的脚本(windows)

如何通过双击在 OS X 中运行 shell 脚本?

如何从 Mac 的 Spotlight 运行 Python 脚本(而不必打开终端或 Pycharm)?

Python,Discord bot 未回复消息且终端未更新

打开终端并运行 shell 脚本(CentOS)后出现 Bash 错误 [重复]

我如何在与关闭终端相同的工作目录中打开终端?