Поиск…


Вступление

Существует много способов взаимодействия с операционной системой. Внутри Ruby вы можете запускать командные команды или подпроцессы.

замечания

Exec:
Exec очень ограничен по функциональности, и когда он будет выполнен, выйдет из программы Ruby и запустит команду.

Системная команда:
Команда System запускается в под-оболочке вместо замены текущего процесса и возвращает true или nill. Системная команда, как и обратные операции, выполняет операцию блокировки, когда основное приложение ожидает, пока результат операции системы не завершится. Здесь основной операции никогда не нужно беспокоиться о том, чтобы зафиксировать исключение, вызванное дочерним процессом.

Вывод системной функции всегда будет true или nil в зависимости от того, был ли сценарий выполнен без ошибок. Поэтому каждая ошибка при выполнении сценария не будет передана нашему приложению. Основная операция никогда не должна беспокоиться о захвате исключения, вызванного дочерним процессом. В этом случае вывод равен нулю, поскольку дочерний процесс вызывает исключение.
Это операция блокировки, когда программа Ruby будет ждать завершения операции команды перед продолжением.
Операция системы использует fork для разветвления текущего процесса, а затем выполнения данной операции с помощью exec.

Выходы (`):
Символ обратного хода обычно расположен под клавишей эвакуации на клавиатуре. Backticks запускается в под-оболочке вместо замены текущего процесса и возвращает результат команды.
Здесь мы можем получить вывод команды, но программа выйдет из строя, когда генерируется исключение.
Если в подпроцессе есть исключение, это исключение предоставляется основному процессу, и основной процесс может завершиться, если исключение не обрабатывается. Это операция блокировки, когда программа Ruby будет ждать завершения операции команды перед продолжением.
Операция системы использует fork для разветвления текущего процесса, а затем выполнения данной операции с помощью exec.

IO.popen:
IO.popen работает в подпроцессе. Здесь стандартный входной сигнал и стандартный вывод подключаются к объекту ввода-вывода.

Popen3:
Popen3 позволяет получить доступ к стандартным входам, стандартным выводам и стандартной ошибке.
Стандартный ввод и вывод подпроцесса будут возвращены в объекты IO.

$? (так же, как $ CHILD_STATUS)
Может использоваться с операциями backticks, system () или% x {} и будет выдавать статус последней команды, выполненной системой.
Это может быть полезно для доступа к exitstatus и pid .

$?.exitstatus

Рекомендуемые способы выполнения кода оболочки в Ruby:

Open3.popen3 или Open3.capture3:
Open3 фактически просто использует команду Ruby's spawn, но дает вам гораздо лучший API.

Open3.popen3

Popen3 запускается в подпроцессе и возвращает stdin, stdout, stderr и wait_thr.

require 'open3'
stdin, stdout, stderr, wait_thr = Open3.popen3("sleep 5s && ls")
puts "#{stdout.read} #{stderr.read} #{wait_thr.value.exitstatus}"

или же

require 'open3'
cmd = 'git push heroku master'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
  puts "stdout is:" + stdout.read
  puts "stderr is:" + stderr.read
end

будет выводиться: stdout: stderr is: fatal: не репозиторий git (или любой из родительских каталогов): .git

или же

require 'open3'
cmd = 'ping www.google.com'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
  while line = stdout.gets
    puts line
  end
end

выведет:

Pinging www.google.com [216.58.223.36] с 32 байтами данных:
Ответ от 216.58.223.36: байты = 32 раза = 16 мс TTL = 54
Ответить от 216.58.223.36: bytes = 32 time = 10ms TTL = 54
Ответ от 216.58.223.36: байты = 32 раза = 21 мс TTL = 54
Ответить от 216.58.223.36: bytes = 32 time = 29ms TTL = 54
Статистика Ping для 216.58.223.36:
Пакеты: Отправлено = 4, Получено = 4, Потеряно = 0 (потеря 0%),
Приблизительное время прохода в миллисекундах:
Минимум = 10 мс, Максимум = 29 мс, Средний = 19 мс


Open3.capture3:

require 'open3'

stdout, stderr, status = Open3.capture3('my_funky_command', 'and', 'some', 'argumants')
if status.success?
  # command completed successfully, do some more stuff
else
  raise "An error occured"
end

или же

Open3.capture3('/some/binary with some args')  

Не рекомендуется, однако, из-за дополнительных накладных расходов и возможности для инъекций оболочки.

Если команда считывает из stdin и вы хотите передать ей некоторые данные:

Open3.capture3('my_funky_command', stdin_data: 'read from stdin')  

Запустите команду с другим рабочим каталогом, используя chdir:

Open3.capture3('my_funky_command', chdir: '/some/directory')  

Класические способы выполнения кода оболочки в Ruby:

Exec:

exec 'echo "hello world"'

или же

exec ('echo "hello world"')

Системная команда:

system 'echo "hello world"'

Выведет «hello world» в командном окне.

или же

system ('echo "hello world"')

Системная команда может вернуть значение true, если команда была успешной или nill, когда нет.

result = system 'echo "hello world"'
puts result  # will return a true in the command window

Выходы (`):

echo "hello world" Выведет «hello world» в командном окне.

Вы также можете поймать результат.

result = `echo "hello world"`  
puts "We always code a " + result  

IO.popen:

# Will get and return the current date from the system
IO.popen("date") { |f| puts f.gets }


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow