Как написать на другой терминал с запущенной программой в Python 2.7? - PullRequest
0 голосов
/ 24 февраля 2019

В настоящее время я делаю программу на python для открытия серверов Minecraft.Я уже сделал окно, где вы можете выбрать сервер в списке и запустить его или сделать резервную копию.Когда вы запускаете его, открывается новый терминал (с os.system('gnome-terminal...')) и запускается java-программа.Есть ли способ отправить некоторый текст (например, команды) в эту Java-программу с первого терминала?

Вот мой код

Я пробовал много вещей сподпроцесс, но без удовлетворительного результата.

РЕДАКТИРОВАТЬ :

#!/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()

1 Ответ

0 голосов
/ 24 февраля 2019

Во-первых, никогда не используйте os.system.Всегда используйте модуль subprocess для запуска новых процессов, поскольку он намного лучше обрабатывает многие крайние случаи.subprocess.check_call может сделать все, что может os.system, и многое другое, и он проверяет ошибки, чего-то os.system не делает.

Во-вторых, не используйте gnome-terminal для создания интерактивноготерминал для запуска вашего подпроцесса!Вместо этого создайте псевдотерминал (pty);Таким образом, ваша программа может контролировать поведение ребенка.Под капотом работает такая программа, как gnome-terminal: она создает pty для оболочки и запускаемых оболочкой программ, а затем читает из pty и визуализирует результаты графически.

Ваша программа может создать pty для каждой дочерней программы, которую вы хотите запустить, и тогда ваша программа может взаимодействовать с дочерней программой точно так же, как gnome-terminal.Вы можете сделать это с помощью модуля pty в стандартной библиотеке Python, но вы можете рассмотреть возможность использования пакета pexpect, поскольку это существенно упрощает процесс.

Если вам не нужна полная версиятерминал, вы можете сделать это еще проще, просто открыв канал для дочернего процесса.Модуль subprocess в стандартной библиотеке предоставляет класс Popen, который можно использовать для этого.

В вашем конкретном случае я бы порекомендовал pexpect.Он прост в использовании и будет «делать правильные вещи» для такой работы.

...