1

I have debugged my code for a while and I found out that bash_shell(message,shell) fails to pass the shell dictionary back to the main process. The dictionary is still blank but when I read (actually, print) shell in bash_shell(), it does have the value. Which means maybe because I passed the value of the variable but not the alias? But I saw other posts in other websites, people do it in that way and it works fine.

And I tried to do threading.Thread() instead of multiprocessing.Process(). The thread can pass the value back with global variables (didn't try the parameter method).

import multiprocessing,subprocess
# doing import stuff and blah blah blah
shell = dict()
shell['sh_out'] = ''
shell['py_out'] = ''
# code.... (in this part I also defined channel, guild, _globals, _locals,bot, etc...)
def bash_shell(msg,shell):
    global channel,guild,_globals,_locals
    try:
        proc = subprocess.Popen(msg.split(" "), stdout=subprocess.PIPE,text=True)
    except Exception as e:
        shell['sh_out'] = str(e) + '\n$'
        return
    (out, err) = proc.communicate()
    if err:
        shell['sh_out'] = '```\n' + str(out) + "\n```\nError: `" + str(err) + "`\n```\n$```"
    else:
        shell['sh_out'] = '```\n'+ str(out) + "\n$```"
    if len(rt) > 1988:
        f = open("samples/shoutput.txt","w")
        f.write(rt)
        f.close()
    return
#code.......
# @bot.event
def on_message(message):
    #again code......
    # if message.channel.name == 'bash':
        # p = multiprocessing.Process(target=bash_shell,args=[message,shell])
        p = multiprocessing.Process(target=bash_shell,args=['ls -al',shell])
        p.start()
        p.join(5)
        if p.is_alive():
            p.kill()
            shell['sh_out'] = "Enough fork bomb. Please don't try to hang the bot."
            p.join()
        if len(shell['sh_out']) > 1998:
            # await message.channel.send(file=discord.File(open("samples/shoutput.txt","r"),"output.txt"))
            shell['sh_out'] = ''
            return
        print(shell)
        # await message.channel.send(shell['sh_out'])
        shell['sh_out'] = ""
        return

on_message('a')

(note: if you wonder what I am doing, it's just a bot coded in discord.py. Code has been modified so that it is more understandable and easy to trigger the exception.)

So what did I do wrong? Or are there better ways to do the trick? Why can't it changes the dictionary shell but other people can do so?

5
  • Processes don't share memory space with each other. If you make another process, the old one is copied. Whatever changes you make, they don't persist. Commented Apr 26, 2020 at 2:48
  • so with that being said, I have to pass the pointer? But why this works? It is the same thing. Commented Apr 26, 2020 at 2:51
  • It has nothing to do with pointers vs ordinary values. multiprocessing library knows that objects created with multiprocessing.Manager need to be later synced up. Commented Apr 26, 2020 at 2:57
  • oh nvm I figured it out. multiprocessing.Manager().dict() Thanks. Commented Apr 26, 2020 at 2:58
  • 1
    Hi : check this out google.com/amp/s/www.geeksforgeeks.org/… Commented Apr 26, 2020 at 4:29

1 Answer 1

2

You have two possibility:

1 ) Share Memory space between processes

2 ) Use the Manager Object provided by the multiprocessing library

But for the communication between process, you can use a Queue as mentionned in this excellent article :

https://www.geeksforgeeks.org/multiprocessing-python-set-2/amp/

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.