Выполнение командной строки управляет в рамках сценария Ruby

Существует ли путь к командам строки команды выполнения через Ruby? Я пытаюсь создать маленькую небольшую программу Ruby, которая набрала бы и получила бы/отправила бы через программы командной строки как 'экран', 'rcsz', и т.д.

Было бы замечательно, если я мог бы согласоваться все это в Ruby (бэкенд MySQL, и т.д.)

89
задан geetfun 1 July 2010 в 16:56
поделиться

3 ответа

Есть несколько способов запускать системные команды в 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 , который специально предлагает эту возможность.

14
ответ дан 24 November 2019 в 07:12
поделиться

Да. Есть несколько способов:


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 в программу.


б. Использовать систему :

system 'echo hi' #=> true (prints 'hi')
system 'echo hi >&2' #=> true (prints 'hi' to stderr)
system 'exit 1' #=> nil

Этот метод возвращает истину , если команда была успешной. Он перенаправляет весь вывод в программу.


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 , который повторяет ввод / вывод новых процессов. В настоящее время это единственный известный мне способ ввести программу.


ф. Используйте 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.

205
ответ дан 24 November 2019 в 07:12
поделиться

Да, это, конечно, возможно, но метод реализации зависит от того, работает ли программа "командной строки" в полноэкранном режиме или в режиме командной строки. Программы, написанные для командной строки, обычно читают STDIN и пишут в STDOUT. Их можно вызывать непосредственно в Ruby, используя стандартные методы backticks и/или вызовы system/exec.

Если программа работает в "полноэкранном" режиме, как screen или vi, то подход должен быть другим. Для подобных программ вам следует искать реализацию библиотеки "expect" в Ruby. Это позволит вам написать сценарий того, что вы ожидаете увидеть на экране, и что послать, когда на экране появятся эти конкретные строки.

Это вряд ли будет лучшим подходом, и вам, вероятно, следует посмотреть, чего вы пытаетесь достичь, и найти соответствующую библиотеку/гем для этого, а не пытаться автоматизировать существующее полноэкранное приложение. Например, "Need help with serial port communications in Ruby" имеет дело с Serial Port communications, прекурсором к набору номера, если это то, чего вы хотите достичь, используя конкретные программы, которые вы упомянули.

2
ответ дан 24 November 2019 в 07:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: