From: bwv549 Date: 2009-12-17T14:45:12+09:00 Subject: Re: working with a slow pipe (IO.popen) @Robert: I've looked through a lot of pymol docs and haven't found anything on it yet, will post if I do. The solution you post looks very intriguing. It runs fine, but closes before I get back the output I need. It seems like there must be some kind of a pause to let pymol start spitting out output. I may play around with it some to see if I can get it working. @Eric: this solution works nicely and returns all the expected output. I will be using it unless something better comes along. Thanks to both of you for your excellent input on this. --John On Dec 16, 1:05 am, Robert Klemme wrote: > 2009/12/16 bwv549 : > > > > > On Dec 15, 11:32 pm, Eric Wong wrote: > >> bwv549 wrote: > >> > I'm doing some work with pymol and having trouble getting all the > >> > pymol output out: > > >> > # I open it in quiet/commandline mode with a pipe: > >> > IO.popen("pymol -cq -p", 'w+') do |pipe| > >> >   pipe.puts "load file.pdb, mymodel\n" > >> >   pipe.puts "run my_script.py" > >> >   # this command will generate a whole bunch of output to stdout > >> >   pipe.puts "my_script mymodel" > >> >   sleep(5)  # <--- this is what I have to do in order to get the > >> > output > >> >   pipe.close_write > >> >   output = pipe.read > >> > end > > >> > What is annoying is that unless I sleep for 2-5 seconds I don't get > >> > output or (even worse) my output is cut off.  There has to be a way > >> > besides arbitrarily sleeping to ensure that the command is finished. > >> > I've tried things like piping in "quit", but that doesn't seem to > >> > work.  Anybody know how to solve this?  I'm happy to use a different > >> > approach if it means I can be sure I get all of my output out.   -- > >> > Thanks! > > >> Hi, > > >> I don't know about pymol, but some apps do not respond well to having > >> its stdin closed on it with close_write.  pipe.read should just block > >> until you get output, otherwise put an IO.select([pipe) in front of it. > > >> Does this work? > > >>   IO.popen("pymol -cq -p", 'w+') do |pipe| > >>     pipe.puts "load file.pdb, mymodel\n" > >>     pipe.puts "run my_script.py" > >>     pipe.puts "my_script mymodel" > > >>     # IO.select([pipe]) # you shouldn't need to uncomment this... > > >>     output = pipe.read > >>   end > > >> -- > >> Eric Wong > > > both of those hang indefinitely.  It doesn't hang if I add the line: > > >   pipe.puts "quit" > > > but that doesn't give me all the output either.  So maybe pymol > > behaves differently than many commandline programs? > > What does the documentation of "pymol" say? > > > > > Here is what I've worked out for the time being.  It opens a thread > > for reading the output and asks if there is any output every 1/2 > > second.  Once we go 1/2 second without output we kill the thread. > > > my_string = "" > > Open3.popen3("pymol -cq -p") do |si, so, se| > >  si.puts "load file.pdb, mymodel\n" > >  si.puts "run my_script.py\n" > >  si.puts "myscript mymodel\n" > > >  forstdout = Thread.new do > >    Thread.current['lines'] = [] > >    while line = so.gets > >      Thread.current['lines'] << line > >    end > >  end > > You don't need the thread local for this to work.  Note there is also > Thread#value! > > How does this work: > > output = IO.popen("pymol -cq -p", 'w+') do |pipe| >   reader = Thread.new { pipe.to_a } > >   pipe.puts "load file.pdb, mymodel" >   pipe.puts "run my_script.py" >   # this command will generate a whole bunch of output to stdout >   pipe.puts "my_script mymodel" > >   pipe.close_write >   reader.value > end > > Kind regards > > robert > > -- > remember.guy do |as, often| as.you_can - without endhttp://blog.rubybestpractices.com/