How to open terminal and run script and then close it by discord bot

Viewed 296

I'm trying to make a discord bot to start my minecraft sever via discord. That what I have at the moment.

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

As in code, I want to open terminal and execute bash script to run server and then, when it's time to turn it off, I want to kill terminal or send "stop" into console.

EDIT: I tried to use subprocess.Popen, but I can't close it from another if statment than i execute that first time

@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

That's the output:

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
1 Answers

The current error: UnboundLocalError: local variable 'ngrok' referenced before assignment This means that 'ngrok' wasn't initialized (defined) before the ngrok.terminate() was called. It happened because you initialize your ngrok in the if conditional above, but say, what if you never run through that conditional? Then ngrok will never be defined as anything. What you want to do is initialize it first.

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

However, I don't see server defined anywhere as well. More errors may arise. If you would like more assistance, please provide sample reproducible code.

Related