From: Brian Candler Date: 2003-05-07T19:31:39+09:00 Subject: Re: capture output On Wed, May 07, 2003 at 06:55:54PM +0900, Simon Strandgaard wrote: > What should I do in order to capture output to a string ??? You can't, in the way that you showed. You must use IO.popen as I said before. The problem is this: you are forking a child process, which inherits stdin/stdout/stderr. It then writes to them using *Unix* write() calls, to file descriptors 1 (stdout) and 2 (stderr). Now, you can redirect fds 1/2 to a file before forking, in which case the child will write to that file. But you cannot redirect those fds to a Ruby object, because the Unix write() syscall does not call Ruby! Now, if you use IO.popen, then you will set up an unnamed Unix pipe between your application and the child. Any data written by the child will be sent using write() into the pipe, and your application can pick it up and do whatever it likes - such as appending it to a Ruby string. However that's only a single pipe, so that app that you spawn will still have to remember to redirect stderr to stdout if you want to capture both. The shell can do that for you using fd redirection: data = nil IO.popen("cat /etc/shadow 2>&1") do |f| data = f.read end p data #>> "cat: /etc/shadow: Permission denied\n" Note that if the command does not exist (e.g. replace 'cat' with 'kat') then the shell will still write directly to its stderr. But in general, I think it's the right thing to let stderr do its job, of giving an out-of-band error reporting channel. Regards, Brian.