From: "Ara.T.Howard" Date: 2004-02-17T06:14:57+09:00 Subject: Re: controlling external process' stdin/stdout AND getting its return value On Tue, 17 Feb 2004, Ferenc Engard wrote: > Date: Tue, 17 Feb 2004 05:06:08 +0900 > From: Ferenc Engard > 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 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 -- =============================================================================== | 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 ===============================================================================