Как записать вывод скрипта в STDOUT и файл

У меня есть следующий блок Ruby:

ruby_block "Validate" do
  block do
    require "mixlib/shellout"
    begin
      cmd = Mixlib::ShellOut.new("/usr/local/bin/someScript.py", :timeout => 3600)
      cmd.live_stream = STDOUT
      cmd.run_command
      cmd.error!
    rescue Exception => e
      puts "Action failed..."
      return 168
    end
  end
  action :create
  notifies :create, "ruby_block[Validated]", :immediately
  not_if { node[:state][:validated] == true }
end

Я хочу записать результат скрипта в STDOUT и файл с именем "/tmp/xml_diff_results.txt".

Первое, что я сделал, было изменение:

cmd=Mixlib::ShellOut.new("/usr/local/bin/someScript.py", :timeout => 3600)

чтобы:

cmd=Mixlib::ShellOut.new("/usr/local/bin/someScript.py > /tmp/xml_diff_results.txt", :timeout => 3600)

однако, это не сделало то, что я ожидал.

Затем я заметил cmd.live_stream переменная. Есть ли способ, которым я могу воспользоваться этим и сделать что-то подобное?:

cmd.live_stream = (STDOUT > /tmp/xml_diff_results.txt)

РЕШЕНИЕ:

Решение моей проблемы было простым и вдохновлено @tensibai.

log_file = File.open('/tmp/chef-run.log', File::WRONLY | File::APPEND)
LOG = Logger.new(log_file)

def shell(command)
  LOG.info "Execute: #{command}"
  cmd = Mixlib::ShellOut.new(command, :timeout => 1800)
  cmd.run_command
  LOG.info "Returned: #{cmd.stdout}"
  cmd.error!
  cmd
end

2 ответа

Решение

Еще один вариант в Ruby (только внутренняя часть) на случай tee недоступно (окна):

  cmd = Mixlib::ShellOut.new("/usr/local/bin/someScript.py", :timeout => 3600)
  cmd.live_stream = STDOUT
  cmd.run_command
  # new part
  log=::Tempfile.new(["xml_diff_results",".txt"])
  errlog=::File.open(log.path.gsub(".txt",".err")
  log.write(cmd.stdout)
  errlog.write(cmd.stderr)
  log.close
  errlog.close
  Chef::Log.info("Log results are in #{log.path}")
  # end of new part 
  cmd.error!

Изменить Chef::Log уровень до warn если вы запускаете Chef-клиент без -l info и действительно хочу, чтобы путь был напечатан в журнале шеф-повара.

Основным преимуществом является то, что он не зависит от платформы, недостатком является то, что файлы журнала будут записываться только после завершения выполнения команды.

Это не вопрос Ruby или даже Chef. Это больше похоже на вопрос Bash

Одним из способов запуска команды и перенаправления ее вывода на стандартный вывод и файл может быть использование tee

echo 'Hello World!' | tee output.log

Итак, на вашем примере это может быть так

cmd=Mixlib::ShellOut.new("/usr/local/bin/someScript.py | tee /tmp/xml_diff_results.txt", :timeout => 3600)
Другие вопросы по тегам