Как я могу записать STDOUT и STDERR в один файл и показать только STDERR в консоли, используя Ruby? - PullRequest
0 голосов
/ 01 марта 2011

Я могу сделать что-то подобное в Bash:

myCommand arg1 arg2 2>&1 >> myLogFolder/myLogFile.log | tee -a myLogFolder/myLogFile.log

Я бы хотел сказать следующее:

log.rb myLogFolder/myLogFile.log myCommand arg1 arg2

Использование сценария log.rb позволит выполнить две вещи:

  1. Результатом является более простое утверждение с меньшим количеством уловок перенаправления и только одной спецификацией файла журнала.
  2. При необходимости создайте папку журнала.

Я смотрел на параметры Ruby для popen и spawn, но не вижу способа разделить поток STDERR на два пункта назначения.

Ответы [ 3 ]

0 голосов
/ 01 марта 2011

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

logPath = ARGV[0]
logFolder = File.dirname(logPath)
command = ARGV.slice(1..-1).join(" ")
`mkdir -p #{logFolder}`
exec "#{command} 2>&1 >> #{logPath} | tee -a #{logPath}"
0 голосов
/ 01 марта 2011

Попробуйте эту статью о реализации функциональности, аналогичной tee, с использованием Ruby. Вы должны быть в состоянии использовать это в качестве отправной точки для чисто рубиновой (или, по крайней мере, exec -безопасной) реализации вашего шелл-кода.

0 голосов
/ 01 марта 2011

Вы можете использовать модуль Open3 ( manual ). Он возвращает 3 объекта: stdin, stdout, stderr

Однако вы не можете сохранить порядок между stdout и stderr.

Пример:

#include <stdio.h>

int main(int argc, char *argv[]) {
  fprintf(stdout, "Normal output\n");
  fprintf(stderr, "Error output\n");
  fprintf(stdout, "Normal output\n");
}

Захвачено как:

Normal output
Normal output
Error output

Единственный способ сохранить порядок - запустить программу дважды. : - (

Пример кода рубина:

#!/usr/bin/env ruby

require 'open3'
require 'pathname'

logfile = ARGV.first()
cmd = ARGV.drop(1).join(" ")

dir = Pathname(logfile).dirname

if not File.directory?(dir)
    Dir.mkdir(dir)
end 

file = File.open(logfile, "w")
stdin, stdout, stderr = Open3.popen3(cmd)
stdin.close()

file.puts(stdout.read())
error = stderr.read()
file.puts(error)
puts error

file.close
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...