From: "Cai I." Date: 2010-11-11T03:38:09+09:00 Subject: Re: Can I run windows command line app interactively? Jeremy Bopp wrote in post #959348: > On 11/4/2010 3:52 AM, Cai I. wrote: >> >> # run a command line application >> @session.puts('robocopy.exe ......') >> @session.each do |line| >> p line >> end >> >> The issue is that "@session.each" never stop. It waits when cmd.exe >> waiting for input. So the scripts hang. > > The problem is that @session.each will run until the input stream is > closed, in this case until cmd.exe exits. What you want to do is have > it run only until you get the next prompt waiting for input. For that > you need to use something like the expect module: > > require 'expect' > session = IO.popen('cmd.exe', 'r+') > session.puts('dir') > session.expect(/[CD]:\\.*>/) do > session.puts('robocopy.exe ......') > end > session.expect(/[CD]:\\.*>/) do > session.puts('exit') > end > session.close > > > The only problem with this solution is that you won't be able to see the > output of the commands you run this way. That output is consumed by > #expect, and I don't know of a way to make it print what it consumes. > Of course another way to handle your exact example is something like > this: > > system('dir && robocopy.exe .......') > > > As long as you don't intend to process the output of commands along the > way in order to change how you run the subsequent commands, this should > work for you. If you *do* want to process the output then you could run > each command in a separate session and read the output in between each > session: > > session = IO.popen('dir') > session.each do |line| > puts line > end > session.close > > session = IO.popen('robocopy.exe .....') > session.each do |line| > puts line > end > session.close > > > -Jeremy Thanks a lot Jeremy for reply. I have to get the output for parsing in my scenario, and I finally got it done by monitoring the output and stop read when the prompt found, I guess it likes what the "expect" does. If no prompt found, I will parse out each line and get it processed. I found the function ios.readpartial() very useful in this scenario. I use it to read output from cmd.exe. It won't get blocked at the end of output as long as it has read something. I guess it just read what in the system buffer and return and it only block when nothing left in buffer to read. -- Posted via http://www.ruby-forum.com/.