You can interact with a shell by writing in the pseudo-terminal slave child. Here is a demo of how it could works. This answer is somewhat based on an answer to Linux pseudo-terminals: executing string sent from one terminal in another.
The point is to get the pseudo-terminal used by xterm (through tty
command) and redirect output and input of your method to this pseudo-terminal file. For instance ls < /dev/pts/1 > /dev/pts/1 2> /dev/pts/1
Note that
- xterm child processed are leaked (the use of
os.system
is not recommended, especially for &
instructions. See suprocess
module).
- it may not be possible to find programmatically which tty is used
- each commands are executed in a new suprocess (only input and output is displayed), so state modification command such as
cd
have no effect, as well as context of the xterm (cd
in the 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()
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…