URIS

http://rubyforge.org/frs/?group_id=1024
http://www.codeforpeople.com/lib/ruby/

SYNOPSIS

open child process with handles on pid, stdin, stdout, and stderr

HISTORY

0.4.0:
  - improved error handling contributed by jordan breeding.
  - introduction of background/bg method

0.3.0 :
  - bug fix from jordan breeding.  general clean up.  added spawn method.

0.2.0 :
  - added exception marshaled from child -> parent when exec fails.  thanks
    to jordan breeding for a patch (yay!) and paul brannan for this most
    excellent idea.

0.1.0 :
  - fixed docs to correctly show return value of popen4 (pid first not last).
    thanks Stefanie Tellex <[email protected]> for catching this. 
0.0.0 :
  - initial version

INSTALL

~> gem install open4

SAMPLES

----------------------------------------------------------------------------
simple usage
----------------------------------------------------------------------------

  harp: > cat sample/simple.rb
  require "open4"

  pid, stdin, stdout, stderr = Open4::popen4 "sh"

  stdin.puts "echo 42.out"
  stdin.puts "echo 42.err 1>&2"
  stdin.close

  ignored, status = Process::waitpid2 pid

  puts "pid        : #{ pid }"
  puts "stdout     : #{ stdout.read.strip }"
  puts "stderr     : #{ stderr.read.strip }"
  puts "status     : #{ status.inspect }"
  puts "exitstatus : #{ status.exitstatus }"

  harp: > ruby sample/simple.rb
  pid        : 17273
  stdout     : 42.out
  stderr     : 42.err
  status     : #<Process::Status: pid=17273,exited(0)>
  exitstatus : 0

----------------------------------------------------------------------------
in block form - the child process is automatically waited for
----------------------------------------------------------------------------

  harp: > cat sample/block.rb
  require 'open4'

  status =
    Open4::popen4("sh") do |pid, stdin, stdout, stderr|
      stdin.puts "echo 42.out"
      stdin.puts "echo 42.err 1>&2"
      stdin.close

      puts "pid        : #{ pid }"
      puts "stdout     : #{ stdout.read.strip }"
      puts "stderr     : #{ stderr.read.strip }"
    end

      puts "status     : #{ status.inspect }"
      puts "exitstatus : #{ status.exitstatus }"

  harp: > ruby sample/block.rb
  pid        : 17295
  stdout     : 42.out
  stderr     : 42.err
  status     : #<Process::Status: pid=17295,exited(0)>
  exitstatus : 0

----------------------------------------------------------------------------
exceptions are marshaled from child to parent if fork/exec fails
----------------------------------------------------------------------------

  harp: > cat sample/exception.rb
  require "open4"
  Open4::popen4 "noexist"

  harp: > ruby sample/exception.rb
  /dmsp/reference/ruby-1.8.1//lib/ruby/site_ruby/open4.rb:100:in `popen4': No such file or directory - noexist (Errno::ENOENT)
          from sample/exception.rb:3

----------------------------------------------------------------------------
the spawn method provides and even more convenient method of running a
process, allowing any object that supports 'each', 'read', or 'to_s' to be
given as stdin and any objects that support '<<' to be given as
stdout/stderr.  an exception is thrown if the exec'd cmd fails (nonzero
exitstatus) unless the option 'raise'=>false is given
----------------------------------------------------------------------------

  harp: > cat sample/spawn.rb
  require 'open4'
  include Open4

  cat = '  ruby -e"  ARGF.each{|line| STDOUT << line}  "  '

  stdout, stderr = '', ''
  status = spawn cat, 'stdin' => '42', 'stdout' => stdout, 'stderr' => stderr
  p status
  p stdout
  p stderr

  stdout, stderr = '', ''
  status = spawn cat, 0=>'42', 1=>stdout, 2=>stderr
  p status
  p stdout
  p stderr

  harp: > RUBYLIB=lib ruby sample/spawn.rb
  0
  "42"
  ""
  0
  "42"
  ""

----------------------------------------------------------------------------
the bg/background method is similar to spawn, but the process is
automatically set running in a thread.  the returned thread has several
methods added dynamically which return the pid and blocking calls to the
exitstatus.
----------------------------------------------------------------------------

  harp: > cat sample/bg.rb
  require 'yaml'
  require 'open4'
  include Open4

  stdin = '42'
  stdout = ''
  stderr = ''

  t = bg 'ruby -e"sleep 4; puts ARGF.read"', 0=>stdin, 1=>stdout, 2=>stderr

  waiter = Thread.new{ y t.pid => t.exitstatus } # t.exitstatus is a blocking call!

  while((status = t.status))
    y "status" => status
    sleep 1
  end

  waiter.join

  y "stdout" => stdout

  harp: > ruby sample/bg.rb
  ---
  status: run
  ---
  status: sleep
  ---
  status: sleep
  ---
  status: sleep
  ---
  21357: 0
  ---
  stdout: "42\n"

AUTHOR

ara.t.howard@noaa.gov

LICENSE

ruby's