Python PIPE to popen stdin -
i attempting similar real time subprocess.popen via stdout , pipe
i, however, want send input running process well.
if start process in separate thread using
process = subprocess.popen(cmd,stdout=subprocess.pipe, stderr=subprocess.stdout) i can send input using terminal.
how send input source such separate function not in thread?
i cannot use popen.communicate running process never finish, attempting real time interaction program.
thanks in advance.
here complete code, looking have input sent subprocoess process when send button clicked.
from tkinter import *` ttk import *` import subprocess threading import thread class example(frame): def __init__(self, parent): frame.__init__(self, parent) self.parent = parent self.initui() def initui(self): self.parent.title("test client") self.style = style() self.style.theme_use("default") self.pack(fill=both, expand=1) #label, doesnt change lbl = label(self, text="client:") lbl.grid(row=0, column=1, sticky=w ) #when output client shown global display display = text(self,width=50,height=20) display.grid(row=1, column=1, sticky=e+w+n+s) #where user input taken global prompt prompt = entry(self,width=50) prompt.grid(row=3, column=1, sticky=e+w+n+s) #button send input client send = button(self,text="send",command=self.send) send.grid(row=3, column=2, sticky=n) = button(self,text="get",command=self.get) get.grid(row=2, column=2, sticky=s) def get(self): print foo def send(self): sent = prompt.get() def mythread(): global sent sent = 2 cmd = ['nc', '-l', '-p', '50000'] process = subprocess.popen(cmd,stdout=subprocess.pipe, stderr=subprocess.stdout) while true: out = process.stdout.read(1) if out == '' , process.poll() != none: break if out != '': display.insert(insert, out) sys.stdout.write(out) sys.stdout.flush() def main(): root = tk() root.geometry("500x410+300+300") app = example(root) thread = thread(target = mythread, args=()) thread.start() root.mainloop() if __name__ == '__main__': main()
first, need add stdin=subprocess.pipe popen constructor, , can process.stdin.write process.stdout.read.
but obviously, read can block if there's no data yet, write can block if child isn't reading.
and beyond obvious, it's hard details right using pipes in both directions popen interactive program without blocking anywhere. if want it, @ the source communicate see how works. (there known bugs before 3.2, if you're on 2.x, may have backporting.) have implement code yourself, , if want cross-platform, you're going have whole mess communicate internally (spawning reader , writer threads pipes, etc.), , of course add thread not block main thread on each attempt communicate, , kind of mechanism message main thread when child ready, , on.
alternatively, can @ various "async subprocess" projects on pypi. simplest 1 know of today async_subprocess, gives communicate can use without blocking.
or, if can use twisted (or possibly other event-based networking frameworks), there wrappers around subprocess plug event loop. (if can wait python 3.4, or use work-in-progress tulip on 3.3, someone's built similar around tulip may make 3.4.) , twisted knows how plug tkinter, don't have manually handle 2 separate event loops , communicate between them.
if care modern posix systems (not windows), can make simpler putting pipes in non-blocking mode , writing code if dealing sockets.
but easiest solution use pexpect instead of trying script manually. (as j.f. sebastian points out, pexpect unix-only, can use wrapper around pexpect unix , winpexpect windows.)
Comments
Post a Comment