Как записать вывод скрипта в 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)