【问题标题】:How to write to an other terminal with a running program in it in Python 2.7?如何在 Python 2.7 中使用正在运行的程序写入另一个终端?
【发布时间】:2019-07-18 00:23:54
【问题描述】:

我目前正在用 python 编写一个程序来打开我的世界服务器。我已经完成了一个窗口,您可以在其中选择列表中的服务器并启动它或进行备份。当您启动它时,会打开一个新终端(带有os.system('gnome-terminal...'))并启动 java 程序。有没有办法从第一个终端向这个 java 程序发送一些文本(如命令)?

Here is my code

我用 subprocess 尝试了很多东西,但没有令人满意的结果。

编辑

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

【问题讨论】:

  • 你能把你的代码贴在这里吗?更易于阅读和调试\
  • 一个可能不是最好的选择是设置服务器进程,使其标准输入连接到一个fifo。然后你可以通过写入fifo来发送命令。

标签: python subprocess stdin minecraft gnome-terminal


【解决方案1】:

首先,永远不要使用os.system。始终使用subprocess 模块来启动新进程,因为它可以更好地处理许多边缘情况。 subprocess.check_call 可以做所有os.system 可以做的事情,甚至更多,它会检查错误,而os.system 做不到。

其次,不要使用gnome-terminal 创建交互式终端来运行您的子进程!改为创建一个伪终端(pty);这样你的程序就可以保持对孩子行为的控制。在底层,像 gnome-terminal 这样的程序本身就是这样工作的:它为 shell 创建一个 pty 以及 shell 启动的程序在其中运行,然后它从 pty 中读取并以图形方式呈现结果。

您的程序可以为您要运行的每个子程序创建一个 pty,然后您的程序可以像 gnome-terminal 一样与子程序通信。您可以使用 Python 标准库中的 pty 模块执行此操作,但您可能需要考虑改用 pexpect 包,因为它大大简化了流程。

如果您不需要完整的终端,您可以更简单地通过打开通往子进程的管道来完成此操作。标准库中的subprocess 模块提供了可用于执行此操作的Popen 类。

在您的具体情况下,我会推荐pexpect。它易于使用,并且会为此类工作“做正确的事”。

【讨论】:

    猜你喜欢
    • 2019-02-24
    • 2015-11-23
    • 2016-06-05
    • 2010-11-30
    • 1970-01-01
    • 2019-06-19
    • 2018-10-25
    • 1970-01-01
    • 2016-05-01
    相关资源
    最近更新 更多