Ruby, разница между exec, system и% x () или обратными ссылками - PullRequest
346 голосов
/ 14 июня 2011

В чем разница между следующими методами Ruby?

exec, system и %x() или Backticks

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

Ответы [ 3 ]

381 голосов
/ 05 сентября 2013

system

Метод system вызывает системную программу.Вы должны предоставить команду в качестве строкового аргумента для этого метода.Например:

>> system("date")
Wed Sep 4 22:03:44 CEST 2013
=> true

Вызванная программа будет использовать текущие объекты STDIN, STDOUT и STDERR вашей программы Ruby.Фактически, фактическое возвращаемое значение равно либо true, false, либо nil.В этом примере дата была напечатана через объект ввода-вывода STDIN.Метод вернет true, если процесс завершился с нулевым состоянием, false, если процесс завершился с ненулевым состоянием, и nil, если выполнение не удалось.

Еще один побочный эффект заключается в том, чтоГлобальная переменная $? установлена ​​в объект Process::Status.Этот объект будет содержать информацию о самом вызове, включая идентификатор процесса (PID) вызванного процесса и состояние выхода.

>> system("date")
Wed Sep 4 22:11:02 CEST 2013
=> true
>> $?
=> #<Process::Status: pid 15470 exit 0>

Backticks

Backticks (``) вызывает системную программу и возвращает ее вывод.В отличие от первого подхода, команда предоставляется не через строку, а путем помещения ее в пару обратных символов.

>> `date`
=> Wed Sep 4 22:22:51 CEST 2013   

Глобальная переменная $? также устанавливается через обратные ссылки.С обратными галочками вы также можете использовать интерполяцию строк.

% x ()

Использование %x является альтернативой стилю обратных тегов.Он также вернет вывод.Как и его родственники %w и %q (среди прочих), любой разделитель будет достаточным, если разделители в скобках совпадают.Это означает, что %x(date), %x{date} и %x-date- являются синонимами.Подобно обратным меткам %x может использовать интерполяцию строк.

exec

Используя Kernel#exec текущий процесс (ваш скрипт на Ruby)заменяется процессом, вызванным через exec.Метод может принимать строку в качестве аргумента.В этом случае строка будет подвержена расширению оболочки.Если используется более одного аргумента, то первый используется для выполнения программы, и в качестве аргументов для вызываемой программы предоставляются следующие параметры:

Open3.popen3

Иногда необходимая информация записывается в стандартный ввод или в стандартную ошибку, и вам также необходимо получить контроль над ними.Здесь Open3.popen3 пригодится:

require 'open3'

Open3.popen3("curl http://example.com") do |stdin, stdout, stderr, thread|
   pid = thread.pid
   puts stdout.read.chomp
end
222 голосов
/ 22 июля 2015

Вот блок-схема, основанная на этом ответе .См. Также, с использованием script для эмуляции терминала .

enter image description here

100 голосов
/ 14 июня 2011

Они делают разные вещи. exec заменяет текущий процесс новым процессом, а никогда не возвращает . system вызывает другой процесс, а возвращает его значение выхода текущему процессу. Использование обратных галочек вызывает другой процесс, и возвращает вывод этого процесса текущему процессу.

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