Giving a command in a embedded terminal

2019-02-10 19:23发布

I'm using the following python code to embed a terminal window (from Ubuntu Linux) in a Tkinter window. I would like give the command 'sh kBegin' in the window automatically when the terminal window starts:

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()

Pseudo:

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

How would I get this working?

1条回答
时光不老,我们不散
2楼-- · 2019-02-10 19:44

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

  1. xterm child processed are leaked (the use of os.system is not recommended, especially for & instructions. See suprocess module).
  2. it may not be possible to find programmatically which tty is used
  3. 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()
查看更多
登录 后发表回答