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

Popular posts from this blog

node.js - Bad Request - node js ajax post -

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -