Получение вывода системных вызовов () в Ruby - PullRequest
296 голосов
/ 27 марта 2009

Если я вызываю команду, используя Kernel # system в Ruby, как мне получить ее вывод?

system("ls")

Ответы [ 15 ]

9 голосов
/ 17 мая 2013

Хотя использование обратных кавычек или popen часто является тем, что вам действительно нужно, на самом деле оно не отвечает на заданный вопрос. Могут быть веские причины для захвата system вывода (возможно, для автоматического тестирования). Немного погуглив нашел ответ Я думал, что выложу здесь для блага других.

Так как мне нужно было это для тестирования, мой пример использует настройку блока для захвата стандартного вывода, поскольку фактический вызов system скрыт в тестируемом коде:

require 'tempfile'

def capture_stdout
  stdout = $stdout.dup
  Tempfile.open 'stdout-redirect' do |temp|
    $stdout.reopen temp.path, 'w+'
    yield if block_given?
    $stdout.reopen stdout
    temp.read
  end
end

Этот метод захватывает любой вывод в данном блоке, используя временный файл для хранения фактических данных. Пример использования:

captured_content = capture_stdout do
  system 'echo foo'
end
puts captured_content

Вы можете заменить вызов system на любой внутренний вызов system. Вы также можете использовать аналогичный метод для захвата stderr, если хотите.

8 голосов
/ 26 мая 2013

Если вы хотите, чтобы вывод перенаправлялся в файл с помощью Kernel#system, вы можете изменить дескрипторы так:

перенаправить stdout и stderr в файл (/ tmp / log) в режиме добавления:

system('ls -al', :out => ['/tmp/log', 'a'], :err => ['/tmp/log', 'a'])

Для длительной команды это сохранит выходные данные в режиме реального времени. Вы также можете сохранить вывод с помощью IO.pipe и перенаправить его из системы Kernel #.

7 голосов
/ 04 марта 2010

В качестве прямой замены системы (...) вы можете использовать Open3.popen3 (...)

Дальнейшее обсуждение: http://tech.natemurray.com/2007/03/ruby-shell-commands.html

0 голосов
/ 27 февраля 2017

Я не нашел этого здесь, поэтому добавляя его, у меня были некоторые проблемы с получением полного вывода.

Вы можете перенаправить STDERR в STDOUT, если хотите захватить STDERR, используя кавычка.

output = `grep hosts / private / etc / * 2> & 1`

источник: http://blog.bigbinary.com/2012/10/18/backtick-system-exec-in-ruby.html

0 голосов
/ 08 марта 2016
puts `date`
puts $?


Mon Mar  7 19:01:15 PST 2016
pid 13093 exit 0
...