Reputation:
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?
Upvotes: 1
Views: 1735
Reputation: 3932
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/
Upvotes: 2