Запустите скрипт оболочки из ruby

Я делаю тестирование iOS, используя Фрэнка. Это рубиновый камень, который также использует огурец. У меня есть "заданный" шаг, который проверяет, работает ли приложение или оно не работает. Если мой шаг обнаружит, что произошел сбой, я хотел бы снова запустить приложение. Я запускаю приложение, используя скрипт оболочки, который хранится где-то рядом с файлами огурца.feature.

Как я могу вызвать скрипт из этого определения шага?

4 ответа

Решение

Вы можете сделать это несколькими разными способами

Kernel.system "command"
%x[command]
`command`

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

Обратные кавычки

`command arg1 arg2`
%x(command arg1 arg2)

Запускает команду в подоболочке и возвращает вывод команды. Команда и ее аргументы предоставляются в виде строки, разделенной обратными чертами. Альтернативный синтаксис %x(...) что позволяет избежать проблем, например, когда вы хотите выполнить команду, которая содержит обратные пометки. Скобки могут быть заменены другими разделителями, такими как [], {}, !!... для того, чтобы иметь возможность обойти практически любую проблему, чтобы избежать.

Stderr печатается как обычно, Stdout подавляется. Возвращает вывод stdout команды. Это означает, что вы можете использовать нотацию backtick, чтобы получить выходные данные команды в переменную для дальнейшей обработки.

Kernel.exec

exec("command arg1 arg2")
exec("command", "arg1", "arg2")

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

Kernel.system

system("command arg1 arg2")
system("command","arg1 arg2")

подобно Kernel.exec но снова работает в дольках. Возвращает true если процесс завершился правильно (статус 0), false иначе. Это прекрасно работает внутри if-заявления.

Kernel.spawn

pid = spawn("command")
# do other stuff
Process.wait(pid)

Похожий на Kernel.system но будет порождать дочерний процесс для запуска указанной команды. Таким образом, родительский процесс не будет ожидать завершения выполнения команды, если только Process.wait используется. Возвращаемое значение - это PID порожденного процесса.

IO.popen

io = IO.popen("command")
IO.popen("command") {|io| ... }

Запускает команду в дочернем процессе еще раз, но обеспечивает больший контроль над вводом-выводом. Stdout и stdin дочерних процессов связаны с объектом ввода-вывода, который доступен в качестве возвращаемого значения или параметра блока. Если получено через возвращаемое значение, объект IO должен быть закрыт после использования его с io.close,

open3

Для вариантов использования более продвинутых, чем system или же IO.popen Вы можете использовать Open3 из стандартной библиотеки Ruby. это popen3 Метод позволяет вам вручную взаимодействовать с stdin, stdout и stderr дочернего процесса. open3-х popen2 Метод тот же, за исключением того, что он не дает вам stderr. Пример использования popen2:

require 'open3'

Open3.popen2("wc -c") do |stdin, stdout, status_thread|
  stdin.print "answer to life the universe and everything"
  stdin.close
  p stdout.gets #=> "42\n"
end

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

Другие вопросы по тегам