Tassilo said:
Is there a way to directly redirect my_command's output to stdout? Or
are there other ways to work arround this?
I use IO.popen and Observer to get progress reports for commands.
I have been building an automation framework together with what I call a
test integration framework for my current project.
At th emoment the project is in full steam and there is absolutely no
chance to release the code for public consumption (meaning there is no
time to remove project specific stuff and wrap the whole thing as a
public library that is half-way stable).
Just so, here's what I have done in the lowest level. A Command module
to define a stable interface and DOSCommand which I use to execute
commands on a windows shell (which in turn uses the class that led to
this whole Command thing and which actually is my answer to your
question
).
I have several commands, my favorite being the PressAnyKeyCommand
#This module is the interface for execution of arbitrary commands where we
#need access to the success status, output and execution time for a
command
#
#Check DOSCommand and RubyCommand for some implementations
module Command
attr_writer
utput
def name
return @name
end
def output
init
return @output
end
def working_directory
init
return @working_directory
end
def exec_time
init
return @exec_time
end
def success?
init
return @success
end
def run?
init
return @run
end
def run
init
@run=true
end
def status verbose=false
init
msg=""
if run?
st="succeeded"
st="failed" unless @success
msg+="#{@name} #{st} in #{@exec_time}s\n"
else
msg+="#{@name} was not executed\n"
end
msg+="Working directory:
#{@working_directory}\nLog:\n#{@output}\n" if (!success?||verbose)
return msg
end
#This method initializes the module members with sane values.
#
#It also checks that _working_directory_ is a directory (it
raises RuntimeError if it isn't)
#
#It's a good idea to use this method in the initialize method of
any objects including this module
#but it isn't necessary.
def init name="",working_directory=nil
begin
@name=name
@output="" unless @output
@exec_time=0 unless @exec_time
@working_directory=working_directory
@working_directory=Dir.pwd unless @working_directory
raise "Non-existent working directory: #{working_directory}"
unless File.directory?(@working_directory)
@run=false unless @run
@success=false unless @success
end unless @name
end
end
#Class that wraps the execution of a command in a command shell.
class DOSCommand
include Command
attr_reader:command_line
#If _working_directory_ is specified then the command will be
executed in that directory.
def initialize name,command_line,working_directory=nil
init(name,working_directory)
@command_line=command_line
@cmd=RivaLib::Win::ExecCmd.new(@command_line)
end
#Runs the command.
def run
@run=true
prev_dir=Dir.pwd
begin
Dir.chdir(@working_directory) if @working_directory
@cmd.run
@
[email protected]?
@
[email protected]
@
[email protected]_time
return @success
rescue SystemCallError
return false
ensure
Dir.chdir(prev_dir)
end
end
#Executes a command on a dos shell, redirecting stderr to stdout ("2>&1")
#
#You can then access the output and the return value for the command.
#
#This is meant as a last-resort replacement for popen3 (because of
problems with VC++6.0 and the Ruby One-Click Installer).
#
#_exec_time_ provides the Time spent running the command.
class ExecCmd
attr_reader
utput,:cmd,:exec_time
#When a block is given, the command runs before yielding
def initialize cmd
@output=""
@exec_time=0
@cmd=cmd
@cmd_run=cmd+" 2>&1" unless cmd=~/2>&1/
if block_given?
run
yield self
end
end
#Runs the command
def run
t1=Time.now
IO.popen(@cmd_run){|f|
@output=f.read
@process=Process.waitpid2(f.pid)[1]
}
@exec_time=Time.now-t1
end
#Returns false if the command hasn't been executed yet
def run?
return false unless @process
return true
end
#Returns the exit code for the command.
#
#Returns nil if the command hasn't run yet.
def exitcode
return @process.exitstatus if @process
return nil
end
#Returns true if the command was succesfull.
#
#Will return false if the command hasn't been executed
def success?
return @process.success? if @process
return false
end
end
--
http://www.braveworld.net/riva
____________________________________________________________________
http://www.freemail.gr - äùñåÜí õðçñåóßá çëåêôñïíéêïý ôá÷õäñïìåßïõ.
http://www.freemail.gr - free email service for the Greek-speaking.