7 universal capture of stdout and stderr and handling of child process pid for
12 http://github.com/ahoward/systemu
13 http://rubyforge.org/projects/codeforpeople/
21 - versioning issue. new gem release.
24 - updates for ruby 1.9.1
31 - fixed handling of background thread management - needed
32 Thread.current.abort_on_exception = true
34 - fixed reporting of child pid, it was reported as the parent's pid before
39 <========< samples/a.rb >========>
44 # systemu can be used on any platform to return status, stdout, and stderr of
45 # any command. unlike other methods like open3/popen4 there is zero danger of
46 # full pipes or threading issues hanging your process or subprocess.
50 date = %q( ruby -e" t = Time.now; STDOUT.puts t; STDERR.puts t " )
52 status, stdout, stderr = systemu date
53 p [ status, stdout, stderr ]
57 [#<Process::Status: pid 50931 exit 0>, "2011-12-11 22:07:30 -0700\n", "2011-12-11 22:07:30 -0700\n"]
60 <========< samples/b.rb >========>
65 # quite a few keys can be passed to the command to alter it's behaviour. if
66 # either stdout or stderr is supplied those objects should respond_to? '<<'
67 # and only status will be returned
71 date = %q( ruby -e" t = Time.now; STDOUT.puts t; STDERR.puts t " )
73 stdout, stderr = '', ''
74 status = systemu date, 'stdout' => stdout, 'stderr' => stderr
75 p [ status, stdout, stderr ]
79 [#<Process::Status: pid 50936 exit 0>, "2011-12-11 22:07:30 -0700\n", "2011-12-11 22:07:30 -0700\n"]
82 <========< samples/c.rb >========>
87 # of course stdin can be supplied too. synonyms for 'stdin' include '0' and
88 # 0. the other stdio streams have similar shortcuts
92 cat = %q( ruby -e" ARGF.each{|line| puts line} " )
94 status = systemu cat, 0=>'the stdin for cat', 1=>stdout=''
102 <========< samples/d.rb >========>
107 # the cwd can be supplied
112 pwd = %q( ruby -e" STDERR.puts Dir.pwd " )
114 status = systemu pwd, 2=>(stderr=''), :cwd=>Dir.tmpdir
118 ~ > ruby samples/d.rb
120 /private/var/folders/sp/nwtflj890qnb6z4b53dqxvlw0000gp/T
123 <========< samples/e.rb >========>
128 # any environment vars specified are merged into the child's environment
132 env = %q( ruby -r yaml -e" puts ENV[ 'answer' ] " )
134 status = systemu env, 1=>stdout='', 'env'=>{ 'answer' => 0b101010 }
137 ~ > ruby samples/e.rb
142 <========< samples/f.rb >========>
147 # if a block is specified then it is passed the child pid and run in a
148 # background thread. note that this thread will __not__ be blocked during the
149 # execution of the command so it may do useful work such as killing the child
150 # if execution time passes a certain threshold
154 looper = %q( ruby -e" loop{ STDERR.puts Time.now.to_i; sleep 1 } " )
156 status, stdout, stderr =
157 systemu looper do |cid|
165 ~ > ruby samples/f.rb
167 #<Process::Status: pid 50956 SIGKILL (signal 9)>
168 "1323666451\n1323666452\n1323666453\n"