Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > reading and writing to child process with streams in ruby

Reply
Thread Tools

reading and writing to child process with streams in ruby

 
 
mpurdy
Guest
Posts: n/a
 
      04-08-2011
i am trying to fork a process to run a simple script which requires a
username and password. i made a test case with a simple bash script
and a simple ruby script; however, the ruby script hangs in
stdout.read???

i am new to ruby, so i am assuming i am doing something wrong can
anyone help?

----------------------------------------------------------------------
bash script
----------------------------------------------------------------------
#! /bin/bash
sleep 3
echo -n "username: "
read -e USERNAME
echo -n "password: "
read -e PASSWORD
echo "running your script now for $USERNAME with password $PASSWORD"
echo 'doing something...'
sleep 3
echo 'end doing something...quiting'
exit 0

----------------------------------------------------------------------
ruby script
----------------------------------------------------------------------
require 'open3'

cmd = "./myScript.bash"
#cmd = "gpg --list-keys"
begin
stdin, stdout, stderr = Open3.popen3 cmd
done = 0
until done == 1
begin
line = stdout.read
print "#{line}"
puts line.eql?("username: ")
if line.eql?("username: ")
puts "myuser"
stdin.write "myuser\n"
line = stdout.read
if line.eql?("password: ")
puts "mypassword"
stdin.write "mypassword\n"
done = 1

end
puts "im here!"

end

end

end

end
 
Reply With Quote
 
 
 
 
Y. NOBUOKA
Guest
Posts: n/a
 
      04-08-2011
Hi,

Using IO#readpartial [1] instead of IO#read, you'll see the ruby
script run as expected.
However, I don't know if this is the best way or not.

[1] http://www.ruby-doc.org/core/classes/IO.html#M000917


----------------------------------------------------------------------
ruby script
----------------------------------------------------------------------
require 'open3'

cmd = "./myScript.bash"
#cmd = "gpg --list-keys"
begin
stdin, stdout, stderr = Open3.popen3 cmd

p stdin, stdout, stderr
done = 0
until done == 1
begin
# using IO#readpartial instead of IO#read
line = stdout.readpartial( 4096 )
puts "#{line}"
puts line.eql?("username: ")
if line.eql?("username: ")
puts "myuser"
stdin.write "myuser\n"
# using IO#readpartial instead of IO#read
line = stdout.readpartial( 4096 )
if line.eql?("password: ")
puts "mypassword"
stdin.write "mypassword\n"
done = 1
end
puts "im here!"
end
rescue => err
p err
end
end
end


--
信岡 裕也 (NOBUOKA Yuya)

 
Reply With Quote
 
 
 
 
Brian Candler
Guest
Posts: n/a
 
      04-08-2011
mpurdy wrote in post #991644:
> echo -n "username: "


You are sending just "username: " without a trailing newline.

> line = stdout.read


Here you are reading from stdout until the end-of-file (i.e. until the
other side terminates or closes the file). This will wait forever.

Two possible solutions:

1. Change your shell script to send data ending with a newline, then use
'gets' in the ruby code.

2. More generally, use expect.rb in the standard library. Then you can
wait for a particular sequence of characters, e.g. /name: /, before
continuing.

HTH,

Brian.

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
mpurdy
Guest
Posts: n/a
 
      04-09-2011
On Apr 8, 4:03 am, "Y. NOBUOKA" <(E-Mail Removed)> wrote:
> Hi,
>
> Using IO#readpartial [1] instead of IO#read, you'll see the ruby
> script run as expected.
> However, I don't know if this is the best way or not.
>
> [1]http://www.ruby-doc.org/core/classes/IO.html#M000917
>
> ----------------------------------------------------------------------
> ruby script
> ----------------------------------------------------------------------
> require 'open3'
>
> cmd = "./myScript.bash"
> #cmd = "gpg --list-keys"
> begin
> stdin, stdout, stderr = Open3.popen3 cmd
>
> p stdin, stdout, stderr
> done = 0
> until done == 1
> begin
> # using IO#readpartial instead of IO#read
> line = stdout.readpartial( 4096 )
> puts "#{line}"
> puts line.eql?("username: ")
> if line.eql?("username: ")
> puts "myuser"
> stdin.write "myuser\n"
> # using IO#readpartial instead of IO#read
> line = stdout.readpartial( 4096 )
> if line.eql?("password: ")
> puts "mypassword"
> stdin.write "mypassword\n"
> done = 1
> end
> puts "im here!"
> end
> rescue => err
> p err
> end
> end
> end
>
> --
> 信岡 裕也 (NOBUOKA Yuya)



thanx that did work; however, i after doing more research i agree this
is not the best way. i am a c/c++, java/groovy guy...this ruby stuff
is all new to me; however, after day one; i like it
 
Reply With Quote
 
mpurdy
Guest
Posts: n/a
 
      04-09-2011
On Apr 8, 9:32*am, Brian Candler <(E-Mail Removed)> wrote:
> mpurdy wrote in post #991644:
>
> > echo -n "username: "

>
> You are sending just "username: " without a trailing newline.
>
> > * * * * *line = stdout.read

>
> Here you are reading from stdout until the end-of-file (i.e. until the
> other side terminates or closes the file). This will wait forever.
>
> Two possible solutions:
>
> 1. Change your shell script to send data ending with a newline, then use
> 'gets' in the ruby code.
>
> 2. More generally, use expect.rb in the standard library. Then you can
> wait for a particular sequence of characters, e.g. /name: /, before
> continuing.
>
> HTH,
>
> Brian.
>
> --
> Posted viahttp://www.ruby-forum.com/.


thanx, i looked into it and rewrote the script using the IO.expect and
it worked good. here is my scripts now:

(note: this is just to have an example for myself and team; we will
using ssh so all the passwords will be protected

----------------------------------------------------------------------
bash script
----------------------------------------------------------------------
#! /bin/bash
echo -n "username: "
read -e USERNAME
echo -n "password: "
read -e PASSWORD
echo "running your script now for $USERNAME with password $PASSWORD"
echo 'doing something...'
sleep 1
echo 'end doing something...quiting'
exit 0


----------------------------------------------------------------------
ruby script
----------------------------------------------------------------------
require 'pty' # found in ruby source @ /ext/pty
require 'expect' # found in ruby source @ /ext/pty/lib/expect.rb

#buffer stores the output from the child process
buffer = ""

# spawn a child process (fork)
PTY.spawn("./myScript.bash") do |output, input, pid|
input.sync = true

#set the expect verbosity flag to false or you will get output from
expect
$expect_verbose = false

#get user from environment if posible
if !ENV['USER'].nil?
username = ENV['USER']
else
username = 'guest'
end

#expect the username prompt and return the username
output.expect('username: ') do
input.puts(username)
end

#expect the password prompt and return the password
output.expect('password: ') do
input.puts 'thePassword'
end

#throw away the password comming back to thru the output (note: you
still get the '\n')
output.expect('thePassword') do
end

#read all the output from the process and put it in a buffer for
later
#keep reading until the EOFError exception is thrown
done = 0
while done == 0
begin
buffer += output.readpartial(1024)
rescue EOFError
done = 1
end

end

end

puts "myExcept.rb script ran myScript.bash the results are: \n
#{buffer}"












 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pexpect on windows - child process of another child process - quickquestion Z W Python 0 03-09-2013 10:00 PM
Binary vs. formatted std::string reading/writing to streams Leslaw Bieniasz C++ 2 01-15-2010 11:53 PM
Process.waitFor() returns, but threads reading output/error streams are blocked on read Michael Grove Java 5 08-23-2005 02:24 PM
problem writing to stdin of child process john Perl Misc 7 03-16-2005 09:40 AM
How do I: Main thread spawn child threads, which child processes...control those child processes? Jeff Rodriguez C Programming 23 12-09-2003 11:06 PM



Advertisments