I am currently making a program in python to open minecraft servers. I've already done a window where you can choose a server in a list and launch it or make a backup. When you launch it, a new terminal open (with os.system('gnome-terminal...')
) and the java program starts. Is there a way to send some text (like commands) to this java program from the first terminal ?
I've tried many things with subprocess but without a satisfying result.
EDIT:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import gtk
import re
import os
import time
active_button = 0
servers = [["Server 1","/home/myname/Desktop/server1","server.jar"],
["Serveur 2","/home/myname/Desktop/server2","server.jar"]]
def button_selection(button, num):
global active_button
state=button.state
if state >= 1:
active_button = int(num)
def validation(widget):
path = servers[active_button][1]
server = servers[active_button][2]
command = """gnome-terminal --working-directory="%s" -e 'java -jar %s'""" % (path, server)
print(command)
os.system(command)
def save(widget):
path = servers[active_button][1]
server = servers[active_button][2]
print "cp -a '%s' /home/myname/Documents/backups_minecraft_servers/%s" % (path+"/world", time.strftime("%d_%m_%Y-%T"))
os.system("cp -a '%s' /home/myname/Documents/backups_minecraft_servers/%s" % (path+"/world", time.strftime("%d_%m_%Y-%T")))
print("Backup finished")
def main():
window = gtk.Window()
vbox = gtk.VBox()
hbox = gtk.HBox()
validate = gtk.Button("Validate")
validate.connect("clicked", validation)
backup = gtk.Button("Backup")
backup.connect("clicked", save)
hbox.pack_start(validate)
hbox.pack_start(vbox)
hbox.pack_start(backup)
buttons = [gtk.RadioButton(None, servers[0][0])]
vbox.pack_start(buttons[0])
for server in servers[1:]:
buttons.append(gtk.RadioButton(buttons[0], server[0]))
vbox.pack_start(buttons[-1])
for i in range(len(buttons)):
buttons[i].connect("toggled", button_selection, i)
window.add(hbox)
window.show_all()
gtk.main()
if __name__=="__main__":
main()
First off, don't ever use os.system
. Always use the subprocess
module for launching new processes, as it handles many of the edge cases much better. subprocess.check_call
can do everything os.system
can do, and much more, and it checks for errors, something os.system
doesn't do.
Secondly, don't use gnome-terminal
to create an interactive terminal to run your subprocess in! Create a pseudoterminal (pty) instead; that way your program can maintain control over the behavior of the child. Underneath the hood, that's how a program like gnome-terminal
works itself: it creates a pty for the shell and the programs launched by the shell to run in, and then it reads from the pty and renders the results graphically.
Your program can create a pty for each child program you want to run, and then your program can communicate with the child program exactly like how gnome-terminal
can. You can do this with the pty
module in the Python standard library, but you might want to consider using the pexpect
package instead as it simplifies the process substantially.
If you don't need a full terminal, you can do this even more simply by just opening a pipe to the child process. The subprocess
module in the standard library provides the Popen
class which can be used to do this.
In your specific case I would recommend pexpect
. It's easy to use and will "do the right thing" for this kind of job.