Automating script for a command line utility

I am trying to automate an interactive DOS command line utility (something
like irb)
using ruby 1.7.3 (on Windows 2000).

I tried using IO#popen but could not make the inputs (puts) interlace with
outputs (gets).
I had to batch all the puts’s together before doing the gets.

Any suggestions ?

TIA,
– shanko

Ok, so may be I should explain this with some example code ( here irb is
choosen only for demonstration):

check = IO.popen("ruby c:/ruby/bin/irb.rb",'r+')
check.puts("s = 'abcd'")
check.puts("puts 'matched' if  s=~/a|b|c|d/")
check.puts("puts $:")
check.puts("puts $\"")
check.close_write
check.readlines.each { |line| puts line.upcase unless line =~ 'nil' }

which on my machine (ruby 1.7.3 (2002-11-17) [i386-mswin32]) produces:

irb(main):001:0> s = 'abcd'
 "abcd"
irb(main):002:0> puts 'matched' if  s=~/a|b|c|d/
 matched
irb(main):003:0> puts $:
 C:/ruby/lib/ruby/site_ruby/1.7
 C:/ruby/lib/ruby/site_ruby/1.7/i386-msvcrt
 C:/ruby/lib/ruby/site_ruby
 C:/ruby/lib/ruby/1.7
 C:/ruby/lib/ruby/1.7/i386-mswin32
 .
irb(main):004:0> puts $"
 irb.rb
 e2mmap.rb
 irb/init.rb
 irb/context.rb
 irb/workspace.rb
 irb/extend-command.rb
 irb/ruby-lex.rb
 irb/slex.rb
 irb/ruby-token.rb
 irb/input-method.rb
 irb/locale.rb
 tempfile.rb
 delegate.rb
irb(main):005:0> exit

Notice that I have to club all the “check.puts” functions before the
“check.close_write” and then do readlines

Is there a way to check.puts each command and then immediately read the
lines of output ?
I think IO#popen3 might do this, but it is not available on Windows.

TIA,

– shanko

“Shashank Date” sdate@kc.rr.com wrote in message
news:e90M9.26673$_b.451371@twister.kc.rr.com

···

I am trying to automate an interactive DOS command line utility (something
like irb)
using ruby 1.7.3 (on Windows 2000).

I tried using IO#popen but could not make the inputs (puts) interlace with
outputs (gets).
I had to batch all the puts’s together before doing the gets.

Any suggestions ?

TIA,
– shanko

Hi,

Is there a way to check.puts each command and then immediately read the
lines of output ?

Try to send “STDOUT.sync = true” line first. This is because
the child process buffers stdout. In many UNIX, using pseudo
TTY tells processes to not buffer output, but Windows has no
this feature or similar.

I remember I wrote about this, regarding cygwin and DOS prompt
issue.

I think IO#popen3 might do this, but it is not available on Windows.

Correct, but impossible as OS doesn’t support it.

···

At Thu, 19 Dec 2002 13:14:07 +0900, Shashank Date wrote:


Nobu Nakada

Per nobu’s suggestion, this is what I did:

check = IO.popen("ruby c:/ruby/bin/irb.rb",'w+')
check.puts("STDOUT.sync = true")
check.puts("puts $:")
check.readlines.each { |line| puts line unless line =~ 'nil' }
check.close_write
check.readlines.each { |line| puts line unless line =~ 'nil' }

But the program seemed to hang.
So I killed it (using CTRL+Break in TextPad) and I got this:

Interrupted!

and after a couple of minutes …

C:/ruby/lib/ruby/1.7/irb.rb:234:in `write': Invalid argument

(Errno::EINVAL)
from C:/ruby/lib/ruby/1.7/irb.rb:234:in print' from C:/ruby/lib/ruby/1.7/irb.rb:234:in signal_handle’
from C:/ruby/lib/ruby/1.7/irb.rb:66:in start' from C:/ruby/lib/ruby/1.7/irb.rb:65:in call’
from C:/ruby/lib/ruby/1.7/irb/input-method.rb:49:in gets' from C:/ruby/lib/ruby/1.7/irb/input-method.rb:49:in gets’
from C:/ruby/lib/ruby/1.7/irb.rb:130:in eval_input' from C:/ruby/lib/ruby/1.7/irb.rb:129:in signal_status’
… 14 levels…
from C:/ruby/lib/ruby/1.7/irb.rb:70:in start' from C:/ruby/lib/ruby/1.7/irb.rb:69:in catch’
from C:/ruby/lib/ruby/1.7/irb.rb:69:in `start’
from c:/ruby/bin/irb.rb:13

Tool completed with exit code 4

Please help.

Thanks very much !

– shanko

nobu.nokada@softhome.net wrote in message
news:200212190443.gBJ4hLb24230@sharui.nakada.kanuma.tochigi.jp…

···

Hi,

At Thu, 19 Dec 2002 13:14:07 +0900, > Shashank Date wrote:

Is there a way to check.puts each command and then immediately read the
lines of output ?

Try to send “STDOUT.sync = true” line first. This is because
the child process buffers stdout. In many UNIX, using pseudo
TTY tells processes to not buffer output, but Windows has no
this feature or similar.

I remember I wrote about this, regarding cygwin and DOS prompt
issue.

I think IO#popen3 might do this, but it is not available on Windows.

Correct, but impossible as OS doesn’t support it.


Nobu Nakada

Hello Shashank,

Thursday, December 19, 2002, 8:14:31 AM, you wrote:

Per nobu’s suggestion, this is what I did:

check = IO.popen("ruby c:/ruby/bin/irb.rb",'w+')
check.puts("STDOUT.sync = true")

But the program seemed to hang.

you must exec “sync” at both sides :slight_smile: add after first line

check.sync = true

i use this techinque to work with perl.exe and it really works

···


Best regards,
Bulat mailto:bulatz@integ.ru

Hello Bulat,

“Bulat Ziganshin” bulatz@integ.ru wrote in message

you must exec “sync” at both sides :slight_smile: add after first line

check.sync = true

i use this techinque to work with perl.exe and it really works

Ok, so now I have:

check = IO.popen("ruby c:/ruby/bin/irb.rb",'w+')
check.sync = true
check.puts("STDOUT.sync = true")
check.puts("puts $:")
check.readlines.each { |line| puts line unless line =~ 'nil' }
check.close_write
check.readlines.each { |line| puts line unless line =~ 'nil' }

and it still does not work :-((

Can I see your code which drives perl.exe ?
May be it has something to do with the target application (in your case
“perl.exe” in my case “osql.exe”)
I am using “irb” only as an example.

Thanks,
– shanko