Re: Logging stdout/stderr/stdin of an spawn process (Open4::spawn)



On Apr 29, 12:05 pm, Edgardo Hames <eha...@xxxxxxxxx> wrote:

I need to log all the input (typed by the user) and the stdout/stderr
of a process. The #script method below should behave pretty much like
the Unix script application. This way, my application can issue
several commands, show their output to the user an let them whatever
is needed.

def script cmd, log
        # prepare $stdin to save its content into log
        # prepare $stdout to save its content into log
        # prepare $stderr to save its content into log
        status = Open4::spawn cmd, 'stdin' => $stdin, 'stdout' =>
$stdout, 'stderr' => $stderr
end

I finally managed to do it. Open4::spawn allows any object to be used
as stdin/stdout/stderr as long as they support 'each', 'read', or
'to_s' or '<<'. So I just created a wrapper class that encapsulates
two descriptors logging al I/O operations.

Best regards,
Edgardo


# BEGIN SCRIPT
require 'rubygems'
require 'open4'

class LoggingIO
def initialize io, log
@io = io
@log = log
end

def gets(sep_string=$/)
res = @io.gets(sep_string)
log res
res
end

def << obj
res = @io << obj
log obj
res
end

def log obj
str = obj ? obj.to_s : "(nil)\n"
@log << str
end
private :log
end

def execute cmd, logfile = nil
log = nil
stdin = $stdin
stdout = $stdout
stderr = $stderr

if (logfile)
log = File.open(logfile, 'a+')
stdin = LoggingIO.new($stdin, log)
stdout = LoggingIO.new($stdout, log)
stderr = LoggingIO.new($stderr, log)
end

status = Open4::spawn cmd, 'stdin' => stdin, 'stdout' =>
stdout, 'stderr' => stderr
log.close if log
status
end
# END SCRIPT
.



Relevant Pages

  • Re: Process.BeginErrorReadLine and BeginOutputReadLine; buffer not flushed?
    ... script, and redirects the stdout and stderr output from that script ... That means that if the process gets ahead of your reading process at all, the reading process can still wind up in a thread that's happy to keep reading the stream it's working on, while the OS buffers output sent to the other string. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Process.BeginErrorReadLine and BeginOutputReadLine; buffer not flushed?
    ... script, and redirects the stdout and stderr output from that script ...  But it's not just the StreamReader that does buffering. ...
    (microsoft.public.dotnet.languages.csharp)
  • Open3 with nonblocking reads
    ... I'm currently trying to execute a script within a script, ... single line should contain if it's STDOUT or STDERR, ... STDOuts were passed to the logfile. ...
    (comp.lang.perl.misc)
  • Re: getting stdout and stderr for system calls on windows
    ... It doesn't separate stderr and stdout, but for what I want it, it's more than enough. ... #You can then access the output and the return value for the command. ... def initialize cmd ...
    (comp.lang.ruby)
  • Re: Filter stdout and stderr Together
    ... I would like to write a script that filters lines from both stdout and ... script with the following syntax: ... stderr as expected, but with particular lines filtered out. ...
    (comp.unix.shell)