Controlling external process' stdin/stdout AND getting its return value


(Ferenc Engard) #1

Hi all,

I want total control over an external process, i.e. handle its
stdin/stdout as with IO.popen (also, if it is possible, handle its
stderr, too), and I also need to get is return value.

How can I do this?

Thanks,
Ferenc


(Ara.T.Howard) #2

it’s tricky to manage stdout, stderr, and exit status since with popen you
lose the sense of $?.

try my session module from the raa:

http://raa.ruby-lang.org/list.rhtml?name=session

example:

~ > cat sess.rb

#!/usr/bin/env ruby

http://raa.ruby-lang.org/list.rhtml?name=session

require ‘session’

sh = Session::Shell.new

====

puts "EXAMPLE 0"
stdout, stderr = sh.execute 'ls’
puts "stdout <#{ stdout.inspect }>"
puts "stderr <#{ stdout.inspect }>"
puts "status <#{ sh.status }>"
puts

====

puts "EXAMPLE 1"
stdout, stderr = ‘’, ''
sh.execute ‘ls does-not-exist’, :stdout => stdout, :stderr => stderr
puts "stdout <#{ stdout.inspect }>"
puts "stderr <#{ stdout.inspect }>"
puts "status <#{ sh.exitstatus }>"
puts

====

puts "EXAMPLE 2"
dev_null = open ‘/dev/null’, 'w’
sh.execute ‘ls’, :o => STDOUT, :e => dev_null
puts "status <#{ sh.exit_status }>"
puts

====

puts "EXAMPLE 4"
org = sh.path
p sh.path
sh.path = [’.’] + sh.path
p sh.path
sh.path = "/bin/foo:/bin/bar:#{ sh.path.join ‘:’ }"
p sh.path
sh.path = org
p sh.path
puts

====

puts "EXAMPLE 5"
sh = Session::Shell.new :history => true
sh.execute 'ls’
sh.execute 'echo foobar’
p sh.history[0]
p sh.history[1]
puts

====

puts "EXAMPLE 6"
cmd = 'while test 1; do echo on_out; echo on_err 1>&2; sleep 1; done’
sh.execute(cmd) do |o, e|
puts “processing stdout <#{ o.inspect }>…” if o
puts “processing stderr <#{ e.inspect }>…” if e
end
puts

~ > ruby sess.rb

EXAMPLE 0
stdout <“sess.rb\nsess.rb.out\n”>
stderr <“sess.rb\nsess.rb.out\n”>
status <0>

EXAMPLE 1
stdout <"">
stderr <"">
status <1>

EXAMPLE 2
sess.rb
sess.rb.out
status <0>

EXAMPLE 4
["/data/bin", “/data/bin”, “/usr/kerberos/bin”, “/usr/local/bin”, “/bin”, “/usr/bin”, “/usr/X11R6/bin”, “/usr/local/java/bin”, “.”, “~/bin”, “/sbin”, “/usr/sbin”, “/usr/local/sbin”, “/home/ahoward/bin”]
[".", “/data/bin”, “/data/bin”, “/usr/kerberos/bin”, “/usr/local/bin”, “/bin”, “/usr/bin”, “/usr/X11R6/bin”, “/usr/local/java/bin”, “.”, “~/bin”, “/sbin”, “/usr/sbin”, “/usr/local/sbin”, “/home/ahoward/bin”]
["/bin/foo", “/bin/bar”, “.”, “/data/bin”, “/data/bin”, “/usr/kerberos/bin”, “/usr/local/bin”, “/bin”, “/usr/bin”, “/usr/X11R6/bin”, “/usr/local/java/bin”, “.”, “~/bin”, “/sbin”, “/usr/sbin”, “/usr/local/sbin”, “/home/ahoward/bin”]
["/data/bin", “/data/bin”, “/usr/kerberos/bin”, “/usr/local/bin”, “/bin”, “/usr/bin”, “/usr/X11R6/bin”, “/usr/local/java/bin”, “.”, “~/bin”, “/sbin”, “/usr/sbin”, “/usr/local/sbin”, “/home/ahoward/bin”]

EXAMPLE 5
cmd:
cmdno: <3>
out: <“sess.rb\nsess.rb.out\n”>
err: <"">
cid: <1729_3_142581>

cmd:
cmdno: <4>
out: <“foobar\n”>
err: <"">
cid: <1729_4_69019>

EXAMPLE 6
processing stdout <“on_out\n”>…
processing stderr <“on_err\n”>…
processing stdout <“on_out\n”>…
processing stderr <“on_err\n”>…

(loops forever)

contact me offline with any questions - the current docs are scant but the
above should get you going.

-a

···

On Tue, 17 Feb 2004, Ferenc Engard wrote:

Date: Tue, 17 Feb 2004 05:06:08 +0900
From: Ferenc Engard ferenc@engard.hu
Newsgroups: comp.lang.ruby
Subject: controlling external process’ stdin/stdout AND getting its
return value

Hi all,

I want total control over an external process, i.e. handle its
stdin/stdout as with IO.popen (also, if it is possible, handle its
stderr, too), and I also need to get is return value.

How can I do this?

Thanks,
Ferenc

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: http://www.ngdc.noaa.gov/stp/
TRY :: for l in ruby perl;do $l -e “print “\x3a\x2d\x29\x0a””;done
===============================================================================


(Nobuyoshi Nakada) #3

Hi,

At Tue, 17 Feb 2004 06:14:57 +0900,
Ara.T.Howard wrote in [ruby-talk:92997]:

it’s tricky to manage stdout, stderr, and exit status since with popen you
lose the sense of $?.

$? will be set when the pipe is closed.

···


Nobu Nakada