简体   繁体   中英

Ruby printing output to file with threads

I am writing a Ruby script which loops through some hashes and executes the command in the hash, like so

$conf_info = {                                                                                                                                                            
"OpenSSH"   => {                                                                                                                                                      
    "type"  => "static",                                                                                                                                              
    "cmd"   => %q[sshd -T],                                                                                                                                           
    "msg"   => "Testing OpenSSH Configuration",                                                                                                                       
    "res"   => $cmd_results,                                                                                                                                          
    }
}

I have multiple of these hashes and I loop through all of them, executing each command. I am also using threads. The problem is that I can't output to a file. I have separate threads like this.

threads = []                                                                                                                                                      
get_enums($options[:enumerate])                                                                                                                                   
threads << Thread.new {_run_($sys_info  , $options[:system]     , $enum_sys)   }                                                                                  
threads << Thread.new {_run_($net_info  , $options[:network]    , $enum_net)   }
threads.each {|t| t.join}

and I output to file like this

File.open("test_file", "w") do |file|                                                                                                                                     
    file.puts __start__
end

but, the file is only filled with contents like this

#<Thread:0x98993fc>
#<Thread:0x9872fcc>

and not the actual output of the program. I would also need the program to output to STDOUT and the file, may someone please tell me what I might be doing wrong?

You can't capture output of __start__ by assigning it to a variable. You can redirect output instead:

With TeeIO (Updated based from this answer too):

class TeeIO
  def initialize(*ios)
    ios.each{ |e| raise ArgumentError, "Not an IO object: #{e}" if not e.is_a? IO }
    @ios = ios
  end

  def write(data)
    @ios.each{ |io| io.write(data) }
  end

  def close
    @ios.each{ |io| io.close }
  end

  def flush
    @ios.each{ |io| io.flush }
  end

  def method_missing(meth, *args)
    # Return first if it's not an IO or else return self.
    first = @ios.map{ |io| io.send(meth, *args) }.first
    first.is_a? IO ? self : first
  end

  def respond_to_missing?(meth, include_all)
    @ios.all?{ |io| io.respond_to?(meth, include_all) }
  end
end

...

real_stdout = $stdout
file = File.open("test_file", "w")
$stdout = TeeIO.new(real_stdout, file)

__start__

$stdout = real_stdout
file.close

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM