Яка різниця між наступними методами Ruby?
exec
, system
І %x()
чи Зворотні лапки
Я знаю, що вони використовуються для виконання термінальних команд програмно через Ruby, але я хотів би знати, чому для цього є три різні способи.
Яка різниця між наступними методами Ruby?
exec
, system
І %x()
чи Зворотні лапки
Я знаю, що вони використовуються для виконання термінальних команд програмно через Ruby, але я хотів би знати, чому для цього є три різні способи.
Відповіді:
система
system
Метод викликає системну програму. Ви повинні надати команду як аргумент рядка для цього методу. Наприклад:
>> system("date")
Wed Sep 4 22:03:44 CEST 2013
=> true
Викликана програма буде використовувати струм STDIN
, STDOUT
і STDERR
об'єкти вашої програми Ruby. Насправді, фактичне значення, що повертається або true
, false
або nil
. У прикладі дата була надрукована через об'єкт IO STDIN
. Метод повернеться, true
якщо процес завершився з нульовим статусом, false
якщо процес завершився з ненульовим статусом і nil
якщо виконання не вдалося.
Ще один побічний ефект полягає в тому, що глобальна змінна $?
встановлюється на Process::Status
об'єкт. Цей об'єкт буде містити інформацію про сам виклик, включаючи ідентифікатор процесу (PID) викликаного процесу та статус виходу.
>> system("date")
Wed Sep 4 22:11:02 CEST 2013
=> true
>> $?
=> #<Process::Status: pid 15470 exit 0>
Назад
Повернення (``) викликає системну програму і повертає її вихід. На відміну від першого підходу, команда подається не через рядок, а шляхом введення її всередину пари із зворотними посиланнями.
>> `date`
=> Wed Sep 4 22:22:51 CEST 2013
Глобальна змінна $?
також встановлюється через задні посилання. За допомогою зворотних посилань ви також можете використовувати рядкову інтерполяцію.
% x ()
Використання %x
є альтернативою стилю заднього плану. Він також поверне вихід. Як і його родичі %w
та %q
(серед інших), будь-якого роздільника буде достатньо, доки збігаються обмежувачі у стилі дужок. Це означає %x(date)
, %x{date}
і %x-date-
всі вони є синонімами. Як і в основі зворотних посилань, %x
можна використовувати стропову інтерполяцію.
виконувати
За допомогою 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
STDIN
, STDOUT
, STDERR
, розглянути Open3.popen3
замість; наприклад , див stackoverflow.com/a/10922097/258662
Ось схема, заснована на цій відповіді . Дивіться також використання script
емуляції терміналу .
Вони роблять різні речі. exec
замінює поточний процес новим і ніколи не повертається . system
викликає інший процес і повертає його вихідне значення поточному процесу. За допомогою зворотних посилань викликає інший процес і повертає результат цього процесу в поточний процес.