Ruby, разница между exec, system и% x () или обратными ссылками
370
В чем разница между следующими методами Ruby?
exec, systemИ %x()или Обратные кавычки
Я знаю, что они используются для программного выполнения команд терминала через Ruby, но я хотел бы знать, почему есть три различных способа сделать это.
Так как кто-то только что откопал эту старую ветку, «Работа с процессами Unix» - отличная книга для Rubyists, интересующихся этой темой: workingwithunixprocesses.com
Michael Kohl
1
Я удивлен, что ни один из ответов не упоминает sh.
Деннис
@Dennis Когда я поднимал этот вопрос, ruby 1.9.3 * не был выпущен.
Мистер Блэк,
Ответы:
411
система
systemМетод вызывает системную программу. Вы должны предоставить команду в качестве строкового аргумента для этого метода. Например:
>> system("date")WedSep422:03:44 CEST 2013=>true
Вызванная программа будет использовать ток STDIN, STDOUTи STDERRобъекты вашей программы Ruby. Фактически, фактическое возвращаемое значение либо true, falseлибо nil. В примере дата была напечатана через объект ввода-вывода STDIN. Метод вернется, trueесли процесс завершился с нулевым статусом, falseесли процесс завершился с ненулевым состоянием и nilесли выполнение не удалось.
Другим побочным эффектом является то, что глобальная переменная $?установлена для Process::Statusобъекта. Этот объект будет содержать информацию о самом вызове, включая идентификатор процесса (PID) вызванного процесса и состояние выхода.
>> system("date")WedSep422:11:02 CEST 2013=>true>> $?=>#<Process::Status: pid 15470 exit 0>
Обратные кавычки
Обратные знаки (``) вызывают системную программу и возвращают ее вывод. В отличие от первого подхода, команда предоставляется не через строку, а путем помещения ее в пару обратных символов.
>>`date`=>WedSep422:22:51 CEST 2013
Глобальная переменная также $?устанавливается с помощью обратных кавычек. С помощью обратных галочек вы также можете использовать интерполяцию строк.
%Икс()
Использование %xявляется альтернативой стилю backticks. Он также вернет вывод. Как и его родственники %wи %q(среди прочего), любой разделитель будет достаточным, если разделители в стиле скобок совпадают. Это значит %x(date), %x{date}и %x-date-все это синонимы. Как и обратные пометки, %xможно использовать интерполяцию строк.
Exec
При использовании Kernel#execтекущего процесса (ваш скрипт на Ruby) он заменяется процессом, вызванным через exec. Метод может принимать строку в качестве аргумента. В этом случае строка будет подвержена расширению оболочки. Если используется более одного аргумента, то первый используется для выполнения программы, а в качестве аргументов для вызываемой программы предоставляются следующие параметры.
Open3.popen3
Иногда необходимая информация записывается в стандартный ввод или в стандартную ошибку, и вам также необходимо получить контроль над ними. Здесь Open3.popen3пригодится:
И для более мелкозернистого контроля , как ручки вызова STDIN, STDOUT, STDERR, рассмотреть Open3.popen3вместо; например, см. stackoverflow.com/a/10922097/258662
cboettig
1
Спасибо, что упомянули, что обратные галочки поддерживают интерполяцию строк, что решило мою проблему.
Это не так просто. В моем случае было «нормально (и нужно) блокировать до завершения процесса», чтобы затем использовать popen3 для проверки выходов STDOUT / STDERR.
Накилон
Вы всегда можете вызвать неблокирующий вызов (эффективно) блока, заключив его в цикл while. Вы не можете легко сделать блокирующий вызов неблокирующим.
Ян
106
Они делают разные вещи. execзаменяет текущий процесс новым процессом и никогда не возвращается . systemвызывает другой процесс и возвращает его значение выхода текущему процессу. Использование обратных галочек вызывает другой процесс и возвращает результат этого процесса текущему процессу.
sh
.Ответы:
система
system
Метод вызывает системную программу. Вы должны предоставить команду в качестве строкового аргумента для этого метода. Например:Вызванная программа будет использовать ток
STDIN
,STDOUT
иSTDERR
объекты вашей программы Ruby. Фактически, фактическое возвращаемое значение либоtrue
,false
либоnil
. В примере дата была напечатана через объект ввода-выводаSTDIN
. Метод вернется,true
если процесс завершился с нулевым статусом,false
если процесс завершился с ненулевым состоянием иnil
если выполнение не удалось.Другим побочным эффектом является то, что глобальная переменная
$?
установлена дляProcess::Status
объекта. Этот объект будет содержать информацию о самом вызове, включая идентификатор процесса (PID) вызванного процесса и состояние выхода.Обратные кавычки
Обратные знаки (``) вызывают системную программу и возвращают ее вывод. В отличие от первого подхода, команда предоставляется не через строку, а путем помещения ее в пару обратных символов.
Глобальная переменная также
$?
устанавливается с помощью обратных кавычек. С помощью обратных галочек вы также можете использовать интерполяцию строк.%Икс()
Использование
%x
является альтернативой стилю backticks. Он также вернет вывод. Как и его родственники%w
и%q
(среди прочего), любой разделитель будет достаточным, если разделители в стиле скобок совпадают. Это значит%x(date)
,%x{date}
и%x-date-
все это синонимы. Как и обратные пометки,%x
можно использовать интерполяцию строк.Exec
При использовании
Kernel#exec
текущего процесса (ваш скрипт на Ruby) он заменяется процессом, вызванным черезexec
. Метод может принимать строку в качестве аргумента. В этом случае строка будет подвержена расширению оболочки. Если используется более одного аргумента, то первый используется для выполнения программы, а в качестве аргументов для вызываемой программы предоставляются следующие параметры.Open3.popen3
Иногда необходимая информация записывается в стандартный ввод или в стандартную ошибку, и вам также необходимо получить контроль над ними. Здесь
Open3.popen3
пригодится:источник
STDIN
,STDOUT
,STDERR
, рассмотретьOpen3.popen3
вместо; например, см. stackoverflow.com/a/10922097/258662Вот блок-схема, основанная на этом ответе . Смотрите также, используя
script
для эмуляции терминала .источник
Они делают разные вещи.
exec
заменяет текущий процесс новым процессом и никогда не возвращается .system
вызывает другой процесс и возвращает его значение выхода текущему процессу. Использование обратных галочек вызывает другой процесс и возвращает результат этого процесса текущему процессу.источник