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?
multiprocessinglibrary knows that objects created with multiprocessing.Manager need to be later synced up.multiprocessing.Manager().dict()Thanks.