2010-07-01 135 views
76

有没有办法通过Ruby运行命令行命令?我正在尝试创建一个小型的Ruby程序,它可以通过命令行程序(如“屏幕”,“rcsz”等)拨出和接收/发送。在Ruby脚本中运行命令行命令

如果我能将所有这些与Ruby(MySQL后端等)

回答

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" 

但是如果你需要真正用命令的标准输入/输出进行输入和输出,你可能会想看看IO::popen方法,具体提供了便利。

+0

POPEN效果很好,如果你的应用程序只是有标准的。如果你需要更多的互动还是想做一些与标准输出不同,标准输入和标准错误尤其你也想看看open3:http://ruby-doc.org/core/classes/Open3.html – 2010-07-02 01:26:35

180

是的。有几种方法:


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。(红宝石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对象reperesents的新工艺的输入/输出。这也是目前我知道给节目输入的唯一方法。


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。

+0

精辟概括阿德里安, 感谢您分享这些信息。 – KomodoDave 2012-12-12 12:30:42

+0

奖金把戏:'io = IO.popen'cat> out.log','r +'';将命令的输出写入“out.log” – Narfanator 2013-06-03 04:49:35

+1

每个人的赞成和反对意见是什么。我如何决定使用哪一个?如何使用'FileUtils' [http://ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html]? – Ava 2013-08-15 20:13:37

2

是这当然是可行的,但实现的方法的不同依赖于所讨论的“命令行”的节目是否在“全屏”或命令行模式操作。为命令行编写的程序倾向于读取STDIN并写入STDOUT。这些可以使用标准反引号方法和/或system/exec调用直接在Ruby中调用。

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

这不太可能是最好的方法,你应该看看你想要实现的目标,并找到相关的库/ gem来做到这一点,而不是试图自动化现有的全屏应用程序。作为一个例子与串口通信“Need assistance with serial port communications in Ruby”交易,预光标拨号如果这是你想用你提到的具体方案来实现的。

+0

的简化版本Expect是Ruby中可用使用其内置的[控股](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/pty/rdoc/PTY.html)模块。 – 2013-01-07 23:06:03

6
folder = "/" 
list_all_files = "ls -al #{folder}" 
output = `#{list_all_files}` 
puts output 
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