Running command line commands within Ruby script
有没有办法通过ruby运行命令行命令?我正在尝试创建一个小的Ruby程序,它可以拨出并通过命令行程序(如screen、rcsz等)接收/发送。
如果我能将所有这些与Ruby(MySQL后端等)结合起来,那就太好了。
对。有几种方法:
a.使用
1 2 3 4 5 6 7 | %x(echo hi) #=>"hi " %x(echo hi >&2) #=>"" (prints 'hi' to stderr) `echo hi` #=>"hi " `echo hi >&2` #=>"" (prints 'hi' to stderr) |
这些方法将返回stdout,并将stderr重定向到程序的。
b.使用
1 2 3 | system 'echo hi' #=> true (prints 'hi') system 'echo hi >&2' #=> true (prints 'hi' to stderr) system 'exit 1' #=> nil |
如果命令成功,此方法将返回
c.使用
1 2 3 | 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)使用
1 2 3 4 5 | spawn 'sleep 1; echo one' #=> 430 spawn 'echo two' #=> 431 sleep 2 # This program will print"two one". |
此方法不等待进程退出并返回PID。
e.使用
1 2 3 4 5 6 7 | io = IO.popen 'cat', 'r+' $stdout = io puts 'hi' $stdout = IO.new 0 p io.read(1) io.close # prints '"h"'. |
此方法将返回一个
f.使用
1 2 3 4 5 6 7 8 9 | require 'open3' stdout,stderr,status = Open3.capture3(some_command) STDERR.puts stderr if status.successful? puts stdout else STDERR.puts"OH NO!" end |
在Ruby中有几种运行系统命令的方法。
1 2 3 4 5 6 7 8 9 | irb(main):003:0> `date /t` # surround with backticks =>"Thu 07/01/2010 " 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 " |
但是,如果您需要使用命令的stdin/stdout实际执行输入和输出,您可能需要查看
1 2 3 4 | folder ="/" list_all_files ="ls -al #{folder}" output = `#{list_all_files}` puts output |
是的,这当然是可行的,但是实现方法的不同取决于所讨论的"命令行"程序是在"全屏"模式下运行还是在命令行模式下运行。为命令行编写的程序倾向于读取stdin并写入stdout。可以使用标准的backticks方法和/或system/exec调用在Ruby中直接调用这些函数。
如果程序以"全屏"模式(如screen或vi)运行,则方法必须不同。对于这样的程序,您应该寻找"expect"库的Ruby实现。这将允许您编写您希望在屏幕上看到的内容以及在屏幕上看到这些特定字符串时发送的内容的脚本。
这不太可能是最好的方法,您可能应该看看您正在尝试实现什么,并找到相关的库/gem来实现这一点,而不是尝试自动化现有的全屏幕应用程序。例如,"Reed assistance with serial port communications in ruby"处理串行端口通信,如果您希望使用您提到的特定程序实现拨号,则使用拨号前光标。
最常用的方法是使用
1 2 3 4 5 6 7 8 9 10 | 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 |