简体   繁体   English

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

[英]Running command line commands within Ruby script

Is there a way to run command line commands through Ruby? 有没有办法通过Ruby运行命令行命令? I'm trying to create a small little Ruby program that would dial out and receive/send through command line programs like 'screen', 'rcsz', etc. 我正在尝试创建一个小的Ruby程序,该程序可以通过“ screen”,“ rcsz”等命令行程序拨出并接收/发送。

It would be great if I could tie all this in with Ruby (MySQL backend, etc.) 如果我可以将所有这些与Ruby(MySQL后端等)结合在一起,那将是很棒的

Yes. 是。 There are several ways: 有几种方法:


a. 一种。 Use %x or '`': 使用%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)

These methods will return the stdout, and redirect stderr to the program's. 这些方法将返回标准输出,并将标准错误重定向到程序的标准输出。


b. b。 Use system : 使用system

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

This method returns true if the command was successful. 如果命令成功,则此方法返回true It redirects all output to the program's. 它将所有输出重定向到程序的输出。


c. C。 Use exec : 使用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.

That replaces the current process with the one created by the command. 该命令将当前进程替换为该命令创建的进程。


d. d。 (ruby 1.9) use spawn : (ruby 1.9)使用spawn

spawn 'sleep 1; echo one' #=> 430
spawn 'echo two' #=> 431
sleep 2
# This program will print "two\none".

This method does not wait for the process to exit and returns the PID. 此方法不等待进程退出并返回PID。


e. e。 Use IO.popen : 使用IO.popen

io = IO.popen 'cat', 'r+'
$stdout = io
puts 'hi'
$stdout = IO.new 0
p io.read(1)
io.close
# prints '"h"'.

This method will return an IO object that reperesents the new processes' input/output. 此方法将返回一个IO对象,该对象代表新进程的输入/输出。 It is also currently the only way I know of to give the program input. 这也是目前我所知道的唯一输入程序的方法。


f. F。 Use Open3 (on 1.9.2 and later) 使用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 has several other functions for getting explicit access to the two output streams. Open3还有其他几个功能,可以显式访问两个输出流。 It's similar to popen, but gives you access to stderr. 它类似于popen,但使您可以访问stderr。

There's a few ways to run system commands in Ruby. 有几种方法可以在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"

But if you need to actually perform input and output with the command's stdin/stdout, you'll probably want to look at the IO::popen method, which specifically offers that facility. 但是,如果您实际上需要使用命令的stdin / stdout执行输入和输出,则可能需要查看IO::popen方法,该方法专门提供了该功能。

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

Yes this is certainly doable but the method of implementation differs dependant on whether the "command line" program in question operates in "Full screen" or command line mode. 是的,这当然是可行的,但是实现方法因所讨论的“命令行”程序是以“全屏”还是命令行模式运行而有所不同。 Programs written for the command line tend to read STDIN and write to STDOUT. 为命令行编写的程序倾向于读取STDIN并写入STDOUT。 These can be called directly within Ruby using the standard backticks methods and/or system/exec calls. 可以使用标准的backticks方法和/或system / exec调用在Ruby中直接调用它们。

If the program operates in "Full Screen" mode like screen or vi then the approach has to be different. 如果程序在“全屏”模式(如屏幕或vi)下运行,则方法必须不同。 For programs like this you should look for a Ruby implementation of the "expect" library. 对于这样的程序,您应该寻找“期望”库的Ruby实现。 This will allow you to script what you expect to see on screen and what to send when you see those particular strings appear on screen. 这将使您可以编写脚本,以期望在屏幕上看到的内容以及在屏幕上看到这些特定字符串时发送的内容。

This is unlikely to be the best approach and you should probably look at what you are trying to achieve and find the relevant library/gem to do that rather than trying to automate an existing full screen application. 这不太可能是最好的方法,您可能应该查看要达到的目标并找到相关的库/ gem来做到这一点,而不是尝试使现有的全屏应用程序自动化。 As an example " Need assistance with serial port communications in Ruby " deals with Serial Port communications, a pre-cursor to dialing if that is what you want to achieve using the specific programs you mentioned. 例如,“ 需要帮助Ruby中的串行端口通信 ”处理了串行端口通信,如果您要使用提到的特定程序来实现此目的,则可以使用拨号的前体。

The Most Used method is Using Open3 here is my code edited version of the above code with some corrections: 最常用的方法是使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM