From: "ara.t.howard" Date: 2008-07-18T03:43:00+09:00 Subject: Re: Reading stdout & stderr from a pipe with popen3 On Jul 17, 2008, at 12:22 PM, Matt Mencel wrote: > Well drat.... > > pid, stdin, stdout, stderr = Open4::popen4 "zmprov" > stdin.puts "sm shares" > stdin.puts "gaf" > stdin.close > puts stderr.read.strip if !stderr.read.strip.empty? > puts stdout.read.strip if stderr.read.strip.empty? > stdin.puts "sm shares2" # line 52 > stdin.puts "gaf" > stdin.close > puts stderr.read.strip if !stderr.read.strip.empty? > puts stdout.read.strip if stderr.read.strip.empty? > exit > > > Trying to do that doesn't work, it says the stream is closed and I > can't send anything new to it. > ./pipe_test.rb:52:in `write': closed stream (IOError) > > So I don't want to stdin.close until I'm done processing a bunch of > accounts, but I need to check stdout/stderr after I check each > account without the stdin.close. Is that possible? > > Matt it's entirely up to the client program - this has nothing to do with open4 or any other program. you've got all sorts if issues happening here - you simply need to flush stdin, not close it, if you plan to continue to use it - you are reading to the end of stdout and stderr, this blocks until a program exits, which will not happen until you close stdin, which is why you are needing to do that to see any output - zmprov may or may not buffer stdout and stderr, i have no idea how this program is written an so cannot say basically, if we assume zmprov is written in a line oriented fashion you *might* be able to do something like stdin.puts input output = stdout.gets output if output =~ /error/ .... but i see you are checking stderr too, so you have a problem: you have to read from both stdout and stderr and one, or both, might be empty. you program is going to block until you check both. so you have options - use threads and a queue to check both, develop your own protocol using the code from open4 as an example of how to read from two io objects simultaneously - use select to read from either stdout or stderr, whichever becomes available - re-write zmprov so send all output on stderr and check only that in short your question is impossible to answer without understanding what, *exactly* zmprov does and how it produces output on stdout and stderr. it's also impossible to solve without a solid understanding of how io and, specifically io buffering works. hope that helps. a @ http://codeforpeople.com/ -- we can deny everything, except that we have the possibility of being better. simply reflect on that. h.h. the 14th dalai lama