在嵌入式终端中输入命令

5
我正在使用以下Python代码将终端窗口(来自Ubuntu Linux)嵌入到Tkinter窗口中。当终端窗口启动时,我想自动在窗口中执行命令'sh kBegin':
from Tkinter import *
from os import system as cmd

root = Tk()
termf = Frame(root, height=800, width=1000)

termf.pack(fill=BOTH, expand=YES)
wid = termf.winfo_id()
cmd('xterm -into %d -geometry 160x50 -sb &' % wid)

root.mainloop()

伪类:

cmd('xterm -into %d -geometry 160x50 -sb &' % wid)
embedded_terminal('sh kBegin')
# EMBEDDED TERMINAL DISPLAYS OUTPUT OF sh kBegin##

我该如何使它工作?

如果您不需要进行任何交互,可以使用以下命令:xterm -into ... -sb -hold -e sh kBegin - mgilson
@mgilson 谢谢,但是我确实需要与终端进行交互,并且使用 -font 标签也返回了错误:"xterm -font -adobe-courier-medium-r-normal--18-180-75-75-m-110-iso8859-1 -into %d -geometry 88x37 -sb -hold -e sh kBegin"。我需要能够从Tkinter的按钮按下事件发送命令到终端,比如输入文本 "Hello World && <ENTER>"。感谢你的帮助! :) - abkai
如果您能做到这一点,我也非常感兴趣解决方案!我经常想知道是否可能在tkinter小部件内嵌入任意x11窗口...我认为那将非常棒... - mgilson
这会让你走得更远一点:xterm ... -e "sh kBegin;bash",但不是很多。虽然我不确定你是否能走得更远...(参考)http://www.gossamer-threads.com/lists/python/python/669765 - mgilson
@mgilson 哈哈,好的,如果我真的有所进展,我会告诉你的。我可能最终会转向使用更强大的GUI工具包,因为除了你刚刚建议的之外,我似乎一点运气都没有。我确实设法使用套接字和多个线程设置了一些东西;但这感觉有点毫无意义。 - abkai
请参阅tkterminal,这是一个用于Tkinter的终端小部件。 - milahu
1个回答

8
您可以通过在伪终端从属子进程中编写来与 shell 进行交互。以下是演示如何使用的示例。这个答案在一定程度上基于一个回答:Linux pseudo-terminals: executing string sent from one terminal in another
要点在于获取由 xterm 使用的伪终端(通过 tty 命令)并将您的方法的输出和输入重定向到此伪终端文件。例如,ls < /dev/pts/1 > /dev/pts/1 2> /dev/pts/1 请注意:
  1. xterm 子进程被泄露(不建议使用 os.system,特别是对于 & 指令。请参见 suprocess 模块)。
  2. 可能无法以编程方式找到使用的 tty
  3. 每个命令都在新的子进程中执行(仅显示输入和输出),因此状态修改命令(如 cd)没有影响,xterm 的上下文(cd 在 xterm 中)也没有影响。
from Tkinter import *
from os import system as cmd

root = Tk()
termf = Frame(root, height=700, width=1000)
termf.pack(fill=BOTH, expand=YES)
wid = termf.winfo_id()

f=Frame(root)
Label(f,text="/dev/pts/").pack(side=LEFT)
tty_index = Entry(f, width=3)
tty_index.insert(0, "1")
tty_index.pack(side=LEFT)
Label(f,text="Command:").pack(side=LEFT)
e = Entry(f)
e.insert(0, "ls -l")
e.pack(side=LEFT,fill=X,expand=1)

def send_entry_to_terminal(*args):
    """*args needed since callback may be called from no arg (button)
   or one arg (entry)
   """
    command=e.get()
    tty="/dev/pts/%s" % tty_index.get()
    cmd("%s <%s >%s 2> %s" % (command,tty,tty,tty))

e.bind("<Return>",send_entry_to_terminal)
b = Button(f,text="Send", command=send_entry_to_terminal)
b.pack(side=LEFT)
f.pack(fill=X, expand=1)

cmd('xterm -into %d -geometry 160x50 -sb -e "tty; sh" &' % wid)

root.mainloop()

哇!那个完美地运行了!非常感谢!我会试着玩一下你提供的东西,并将其调整到符合我的需求。但是那个实例完美无缺。谢谢 :) - abkai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接