94

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

如果我可以将所有这些与 Ruby(MySQL 后端等)结合起来,那就太好了。

4

5 回答 5

217

是的。有几种方法:


一个。使用%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)

这些方法将返回标准输出,并将标准错误重定向到程序的。


湾。使用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代表新进程的输入/输出的对象。这也是目前我所知道的给程序输入的唯一方法。


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。

于 2010-07-01T17:03:18.273 回答
14

有几种方法可以在 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专门提供该功能的方法。

于 2010-07-01T17:01:09.103 回答
7
 folder = "/"
 list_all_files = "ls -al #{folder}"
 output = `#{list_all_files}`
 puts output
于 2013-05-31T09:45:51.343 回答
2

是的,这当然是可行的,但实现方法会有所不同,具体取决于所讨论的“命令行”程序是在“全屏”还是命令行模式下运行。为命令行编写的程序倾向于读取 STDIN 并写入 STDOUT。这些可以使用标准的反引号方法和/或系统/执行调用在 Ruby 中直接调用。

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

这不太可能是最好的方法,您可能应该查看您想要实现的目标并找到相关的库/gem 来做到这一点,而不是尝试自动化现有的全屏应用程序。例如,“需要帮助 Ruby 中的串行端口通信”处理串行端口通信,如果您想使用您提到的特定程序实现拨号,则它是拨号的前兆。

于 2010-07-01T17:06:30.487 回答
1

最常用的方法是使用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
于 2017-12-19T06:29:17.997 回答