在Ruby脚本中运行命令行命令

时间:2010-07-01 16:56:23

标签: ruby command-line scripting terminal command-prompt

有没有办法通过Ruby运行命令行命令?我正在尝试创建一个小的Ruby程序,它可以通过'screen','rcsz'等命令行程序拨出和接收/发送。

如果我可以将所有这些与Ruby(MySQL后端等)结合在一起,那将是很棒的

5 个答案:

答案 0 :(得分:198)

是。有几种方法:


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。

答案 1 :(得分:13)

有几种方法可以在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方法。

答案 2 :(得分:7)

 folder = "/"
 list_all_files = "ls -al #{folder}"
 output = `#{list_all_files}`
 puts output

答案 3 :(得分:2)

是的,这肯定是可行的,但实现方法的不同取决于所讨论的“命令行”程序是以“全屏”还是命令行模式运行。为命令行编写的程序倾向于读取STDIN并写入STDOUT。可以使用标准反引号方法和/或system / exec调用在Ruby中直接调用它们。

如果程序在屏幕或vi等“全屏”模式下运行,则方法必须不同。对于这样的程序,您应该寻找“expect”库的Ruby实现。这将允许您编写您希望在屏幕上看到的内容以及当您在屏幕上看到这些特定字符串时要发送的内容。

这不太可能是最好的方法,你应该看看你想要实现的目标,并找到相关的库/ gem,而不是尝试自动化现有的全屏应用程序。例如,“Need assistance with serial port communications in Ruby”处理串行端口通信,如果您希望使用您提到的特定程序实现这一目的,则需要拨打前置光标。

答案 4 :(得分:0)

最常用的方法是使用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