More Related Content Similar to Piloting processes through std IO at the Ruby Drink-up of Sophia, January 2012 (20) Piloting processes through std IO at the Ruby Drink-up of Sophia, January 20121. Piloting processes through standard I/O in Ruby Jan 25 th 2012 Muriel Salvan Open Source Lead developer and architect X-Aeon Solutions http://x-aeon.com 20. This is Line 4, after sleep 1 Output : Output on STDOUT only Output : Output on STDERR only Output : Output for interactive tests only Input : Input taken from STDIN sleep 1 sleep 1 sleep 1 Input from stdin Input from stdin 21. IO::popen IO . popen ( 'ruby test.rb' , 'r+' ) do | io | io . write ( "My String 1 My String 2 " ) io . close_write puts "stdout: #{io.read}” end 25. Does not work with Ruby programs that don't explicitly turn off stdout internal cache 26. Kernel::open Kernel :: open ( '|ruby test.rb', 'r+' ) do | io | puts io . gets # stdout Line 1 puts io . gets # stdout Line 2 puts io . read ( 31 ) # stdout Prompt sleep 1 io . write ( "My String 1 " ) puts io . gets # stdout String 1 sleep 1 io . write ( "My String 2 " ) puts io . gets # stdout Line 3 puts io . gets # stdout Line 4 end 28. Does not work with Ruby programs that don't explicitly turn off stdout internal cache 29. systemu require 'systemu' status, stdout, stderr = systemu ( 'ruby test.rb' , 0 => "My String 1 My String 2 " ) puts "stdout: #{stdout}" puts "stderr: #{stderr}" 31. stdin must be given to the process at startup time => No real time 33. PTY::spawn require 'pty' PTY ::spawn ( 'ruby test.rb' ) do | stdout, stdin, pid | puts stdout. gets # stdout Line 1 puts stdout. gets # stdout Line 2 puts stdout. read ( 31 ) # stdout Prompt sleep 1 stdin. write ( "My String 1 " ) puts stdout. gets # Extra for input echoed puts stdout. gets # stdout String 1 puts stdout. gets # Should be on stderr puts stdout. gets # Should be on stderr puts stdout. read ( 43 ) # Should be on stderr sleep 1 stdin. write ( "My String 2 " ) puts stdout. gets # Extra for input echoed puts stdout. gets # Should be on stderr puts stdout. gets # stdout Line 3 puts stdout. gets # stdout Line 4 end 37. ChildProcess require 'childprocess' require 'tempfile' lProcess = ChildProcess. build ( 'ruby' , 'test.rb' ) lProcess. duplex = true Tempfile . open ( 'stdout' ) do | oStdOUT | lProcess. io . stdout = oStdOUT Tempfile . open ( 'stderr' ) do | oStdERR | lProcess. io . stderr = oStdERR lProcess. start stdout = File . open ( oStdOUT. path , 'r' ) stderr = File . open ( oStdERR. path , 'r' ) stdin = lProcess. io . stdin waitfor ( stdout, 'This is Line 2' ) # Need active wait sleep 1 stdin. write ( "My String 1 " ) waitfor ( stderr, 'This is Line 2' ) # Need active wait sleep 1 stdin. write ( "My String 2 " ) waitfor ( stdout, 'This is Line 4' ) # Need active wait end end 39. Need active blocking read on stdout and stderr to wait for next line 41. Does not work with Ruby programs that don't explicitly turn off stdout internal cache 42. Open3::popen3 require 'open3' Open3 ::popen3 ( 'ruby test.rb' ) do | stdin, stdout, stderr, wait_thr | puts stdout. gets # stdout Line 1 puts stdout. gets # stdout Line 2 puts stdout. read ( 31 ) # stdout Prompt sleep 1 stdin. write ( "My String 1 " ) puts stdout. gets # stdout String 1 puts stderr. gets # stderr Line 1 puts stderr. gets # stderr Line 2 puts stderr. read ( 43 ) # stderr Prompt sleep 1 stdin. write ( "My String 2 " ) puts stderr. gets # stderr String 2 puts stdout. gets # stdout Line 3 puts stdout. gets # stdout Line 4 end 46. ProcessPilot require 'processpilot/processpilot' ProcessPilot ::pilot ( 'ruby' , 'test.rb' ) do | stdin, stdout, stderr, childproc | puts stdout. gets # stdout Line 1 puts stdout. gets # stdout Line 2 puts stdout. read ( 31 ) # stdout Prompt sleep 1 stdin. write ( "My String 1 " ) puts stdout. gets # stdout String 1 puts stderr. gets # stderr Line 1 puts stderr. gets # stderr Line 2 puts stderr. read ( 43 ) # stderr Prompt sleep 1 stdin. write ( "My String 2 " ) puts stderr. gets # stderr String 2 puts stdout. gets # stdout Line 3 puts stdout. gets # stdout Line 4 end 49. Works with all Ruby programs , even if they don't explicitly turn off stdout internal cache 52. Aruba When I run `ruby test.rb` interactively And I type "My String 1" And I type "My String 2" Then the stdout should contain : """ This is Line 1, before sleep 1 This is Line 2, after sleep 1 Enter string 1: String 1 entered: My String 1 This is Line 3, before sleep 1 This is Line 4, after sleep 1 """ And the stderr should contain : " "" This is Line 1 on STDERR, before sleep 1 This is Line 2 on STDERR, after sleep 1 Enter string 2 from STDERR: String 2 entered: My String 2 """ 56. No easy way to test for lines sequence between stdout and stderr flows 64. Aruba (used with Cucumber ) This presentation is available under CC-BY license by Muriel Salvan