bwv549 <jtprince / gmail.com> wrote: > On Dec 15, 11:32m, Eric Wong <normalper... / yhbt.net> wrote: > > bwv549 <jtpri... / gmail.com> 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. here 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. nybody know how to solve this? '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. ipe.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 > > 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? Even IO.select([pipe]) hangs indefinitely? Oh, I guess pymol expects an explicit quit of some sort.... What if you did: IO.select([pipe]) pipe.readpartial(whatever_size_you_are_comfortable_with) > 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. Here's a version without threads, should work the same: 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" # await input for 0.5 seconds, will return nil and # break the loop if there is nothing to read from so after 0.5s while ready = IO.select([so], nil, nil, 0.5) # ready.first == so # in this case # read until the current pipe buffer is empty begin my_string << so.read_nonblock(4096) rescue Errno::EAGAIN break end while true end end -- Eric Wong