Question about run external program in Ruby


#1

I use this method to run a external program in ruby:

io=IO.popen(“lsa 2>&1”)do |f|
while line =f.gets do
puts line
end
end

I can get both stdout and stderr output but how can I get the command
return value?

thanks.


#2

Check $?.exitstatus

On Mon, Jan 5, 2009 at 8:08 AM, Zhao Yi removed_email_address@domain.invalid wrote:

thanks.

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


Andrew T.
http://ramblingsonrails.com
http://www.linkedin.com/in/andrewtimberlake

“I have never let my schooling interfere with my education” - Mark Twain


#3

Andrew T. wrote:

Check $?.exitstatus

I found that $?.exitstatus always return 0.


#4

How can I get stderr in this method?


#5

On Mon, Jan 5, 2009 at 8:08 AM, Zhao Yi removed_email_address@domain.invalid wrote:

thanks.

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

Try the following:
io=IO.popen(“ruby some_file_that_doesnt_exist”)do |f|
while line =f.gets do
puts line
end
end
puts $?.exitstatus
#returns - 1


Andrew T.
http://ramblingsonrails.com
http://www.linkedin.com/in/andrewtimberlake

“I have never let my schooling interfere with my education” - Mark Twain


#6

Another option is the open4 gem. See
http://www.codeforpeople.com/lib/ruby/open4/open4-0.9.6/README
and scroll down to SAMPLES


#7

Zhao Yi wrote:

How can I get stderr in this method?

You are already combining stderr with stdout (2>&1)

To get them separately, see open3.rb in the standard library.

Open3 grants you access to stdin, stdout, and stderr when running

another

program. Example:

require “open3”

include Open3

stdin, stdout, stderr = popen3(‘nroff -man’)

Open3.popen3 can also take a block which will receive stdin, stdout

and

stderr as parameters. This ensures stdin, stdout and stderr are

closed

once the block exits. Example:

require “open3”

Open3.popen3(‘nroff -man’) { |stdin, stdout, stderr| … }

However, since it forks twice, I believe you lose the exit status from
the (grand)child. You also need to be careful not to block on reading
from stdout when the child has written a large amount of data to stderr,
or vice versa. (For example, you could use select, or you could have two
separate threads reading from stdout and stderr)