如何从Ruby程序内部调用shell命令?然后如何将这些命令的输出返回到Ruby中?


当前回答

还有一个选择:

当你:

需要stderr和stdout 不能/不会使用Open3/Open4(他们在我的Mac上的NetBeans中抛出异常,不知道为什么)

你可以使用shell重定向:

puts %x[cat bogus.txt].inspect
  => ""

puts %x[cat bogus.txt 2>&1].inspect
  => "cat: bogus.txt: No such file or directory\n"

从MS-DOS的早期开始,2>&1语法就适用于Linux、Mac和Windows。

其他回答

我绝对不是Ruby专家,但我还是会试一试:

$ irb 
system "echo Hi"
Hi
=> true

你还应该能够做以下事情:

cmd = 'ls'
system(cmd)

还有一个选择:

当你:

需要stderr和stdout 不能/不会使用Open3/Open4(他们在我的Mac上的NetBeans中抛出异常,不知道为什么)

你可以使用shell重定向:

puts %x[cat bogus.txt].inspect
  => ""

puts %x[cat bogus.txt 2>&1].inspect
  => "cat: bogus.txt: No such file or directory\n"

从MS-DOS的早期开始,2>&1语法就适用于Linux、Mac和Windows。

这个解释是基于我的一个朋友写的带注释的Ruby脚本。如果您想改进脚本,请在链接中进行更新。

首先,请注意,当Ruby调用shell时,它通常调用/bin/sh,而不是Bash。在所有系统上/bin/sh不支持某些Bash语法。

以下是执行shell脚本的方法:

cmd = "echo 'hi'" # Sample string that can be used

Kernel#` , commonly called backticks – `cmd` This is like many other languages, including Bash, PHP, and Perl. Returns the result (i.e. standard output) of the shell command. Docs: http://ruby-doc.org/core/Kernel.html#method-i-60 value = `echo 'hi'` value = `#{cmd}` Built-in syntax, %x( cmd ) Following the x character is a delimiter, which can be any character. If the delimiter is one of the characters (, [, {, or <, the literal consists of the characters up to the matching closing delimiter, taking account of nested delimiter pairs. For all other delimiters, the literal comprises the characters up to the next occurrence of the delimiter character. String interpolation #{ ... } is allowed. Returns the result (i.e. standard output) of the shell command, just like the backticks. Docs: https://docs.ruby-lang.org/en/master/syntax/literals_rdoc.html#label-Percent+Strings value = %x( echo 'hi' ) value = %x[ #{cmd} ] Kernel#system Executes the given command in a subshell. Returns true if the command was found and run successfully, false otherwise. Docs: http://ruby-doc.org/core/Kernel.html#method-i-system wasGood = system( "echo 'hi'" ) wasGood = system( cmd ) Kernel#exec Replaces the current process by running the given external command. Returns none, the current process is replaced and never continues. Docs: http://ruby-doc.org/core/Kernel.html#method-i-exec exec( "echo 'hi'" ) exec( cmd ) # Note: this will never be reached because of the line above

这里有一些额外的建议: $ ?,与$CHILD_STATUS相同,如果使用反勾号、system()或%x{},则访问最后一个系统执行命令的状态。 然后你可以访问exitstatus和pid属性:

$?.exitstatus

更多阅读请参见:

http://www.elctech.com/blog/i-m-in-ur-commandline-executin-ma-commands http://blog.jayfields.com/2006/06/ruby-kernel-system-exec-and-x.html http://tech.natemurray.com/2007/03/ruby-shell-commands.html

我最喜欢的是Open3

  require "open3"

  Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }

最简单的方法是:

reboot = `init 6`
puts reboot