Выполнение команд командной строки в Ruby script
Есть ли способ запуска команд командной строки через Ruby? Я пытаюсь создать небольшую небольшую программу Ruby, которая будет набирать и принимать/отправлять через программы командной строки, такие как "screen", "rcsz" и т.д.
Было бы здорово, если бы я мог связать все это с Ruby (MySQL backend и т.д.)
Ответы
Ответ 1
Да. Существует несколько способов:
a. Используйте %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 на программу.
b. Используйте 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. (ruby 1.9) используйте spawn
:
spawn 'sleep 1; echo one' #=> 430
spawn 'echo two' #=> 431
sleep 2
# This program will print "two\none".
Этот метод не ждет завершения процесса и возвращает PID.
e. Используйте 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.
Ответ 2
Есть несколько способов запуска системных команд в 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
, который специально предлагает этот объект.
Ответ 3
folder = "/"
list_all_files = "ls -al #{folder}"
output = `#{list_all_files}`
puts output
Ответ 4
Да, это, безусловно, выполнимо, но метод реализации зависит от того, работает ли программа командной строки в режиме "Полный экран" или в командной строке. Программы, написанные для командной строки, имеют тенденцию читать STDIN и записываться в STDOUT. Они могут быть вызваны непосредственно в Ruby с использованием стандартных методов backticks и/или вызовов system/exec.
Если программа работает в режиме "Полный экран", например, на экране или в vi, то подход должен быть другим. Для таких программ вы должны искать реализацию Ruby библиотеки "ожидать". Это позволит вам script, что вы ожидаете увидеть на экране, и что отправлять, когда вы видите, что эти строки отображаются на экране.
Это вряд ли будет лучшим подходом, и вам, вероятно, следует взглянуть на то, чего вы пытаетесь достичь, и найти соответствующую библиотеку/драгоценный камень, чтобы сделать это, а не пытаться автоматизировать существующее полноэкранное приложение. В качестве примера "Нужна помощь в связях с последовательным портом в Ruby" используется связь с последовательным портом, предварительный указатель на набор, если это то, что вы хотите достичь, используя конкретный которые вы упомянули.
Ответ 5
Самый используемый метод - это использование 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