Есть ли способ запускать команды командной строки через Ruby? Я пытаюсь создать небольшую программу Ruby, которая будет звонить и получать / отправлять через программы командной строки, такие как screen, rcsz и т. Д.
Было бы здорово, если бы я мог связать все это с Ruby (серверная часть MySQL и т. Д.)
Ответы:
Да. Есть несколько способов:
а. Используйте
%x
или '' ':%x(echo hi) #=> "hi\n" %x(echo hi >&2) #=> "" (prints 'hi' to stderr) `echo hi` #=> "hi\n" `echo hi >&2` #=> "" (prints 'hi' to stderr)
Эти методы вернут stdout и перенаправят stderr в файл программы.
б. Использование
system
:system 'echo hi' #=> true (prints 'hi') system 'echo hi >&2' #=> true (prints 'hi' to stderr) system 'exit 1' #=> nil
Этот метод возвращается,
true
если команда была успешной. Он перенаправляет весь вывод в программу.c. Использование
exec
:fork { exec 'sleep 60' } # you see a new process in top, "sleep", but no extra ruby process. exec 'echo hi' # prints 'hi' # the code will never get here.
Это заменяет текущий процесс тем, который был создан командой.
d. (рубин 1.9) используйте
spawn
:spawn 'sleep 1; echo one' #=> 430 spawn 'echo two' #=> 431 sleep 2 # This program will print "two\none".
Этот метод не ожидает завершения процесса и возвращает PID.
е. Использование
IO.popen
:io = IO.popen 'cat', 'r+' $stdout = io puts 'hi' $stdout = IO.new 0 p io.read(1) io.close # prints '"h"'.
Этот метод вернет
IO
объект, который повторяет ввод / вывод новых процессов. Кроме того, в настоящее время это единственный известный мне способ ввести программу.f. Использовать
Open3
(в 1.9.2 и новее)require 'open3' stdout,stderr,status = Open3.capture3(some_command) STDERR.puts stderr if status.successful? puts stdout else STDERR.puts "OH NO!" end
Open3
имеет несколько других функций для получения явного доступа к двум выходным потокам. Он похож на popen, но дает вам доступ к stderr.источник
io = IO.popen 'cat > out.log', 'r+'
; записывает выходные данные команды в "out.log"FileUtils
[ ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html] ?Есть несколько способов запустить системные команды в Ruby.
irb(main):003:0> `date /t` # surround with backticks => "Thu 07/01/2010 \n" irb(main):004:0> system("date /t") # system command (returns true/false) Thu 07/01/2010 => true irb(main):005:0> %x{date /t} # %x{} wrapper => "Thu 07/01/2010 \n"
Но если вам действительно нужно выполнять ввод и вывод с помощью команды stdin / stdout, вы, вероятно, захотите взглянуть на
IO::popen
метод, который специально предлагает эту возможность.источник
folder = "/" list_all_files = "ls -al #{folder}" output = `#{list_all_files}` puts output
источник
Да, это, конечно, выполнимо, но метод реализации отличается в зависимости от того, работает ли рассматриваемая программа «командной строки» в «полноэкранном» или в режиме командной строки. Программы, написанные для командной строки, обычно читают STDIN и записывают в STDOUT. Их можно вызывать непосредственно в Ruby, используя стандартные методы обратных кавычек и / или вызовы system / exec.
Если программа работает в «полноэкранном» режиме, например screen или vi, то подход должен быть другим. Для таких программ вам следует искать Ruby-реализацию библиотеки "expect". Это позволит вам создать сценарий того, что вы ожидаете увидеть на экране и что отправлять, когда вы видите, что эти конкретные строки появляются на экране.
Это вряд ли лучший подход, и вам, вероятно, следует посмотреть на то, чего вы пытаетесь достичь, и найти для этого соответствующую библиотеку / драгоценный камень, а не пытаться автоматизировать существующее полноэкранное приложение. В качестве примера « Требуется помощь в связи через последовательный порт в Ruby » рассматривается связь через последовательный порт, предварение набора номера, если это то, чего вы хотите достичь с помощью конкретных программ, которые вы упомянули.
источник
Наиболее часто используемый метод -
Open3
это моя отредактированная версия кода выше с некоторыми исправлениями:require 'open3' puts"Enter the command for execution" some_command=gets stdout,stderr,status = Open3.capture3(some_command) STDERR.puts stderr if status.success? puts stdout else STDERR.puts "ERRRR" end
источник