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


当前回答

我喜欢的方法是使用%x文字,这使得在命令中使用引号很容易(而且易读!),如下所示:

directorylist = %x[find . -name '*test.rb' | sort]

在这种情况下,它将填充当前目录下的所有测试文件的文件列表,您可以按照预期进行处理:

directorylist.each do |filename|
  filename.chomp!
  # work with file
end

其他回答

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

$ irb 
system "echo Hi"
Hi
=> true

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

cmd = 'ls'
system(cmd)

你也可以使用反勾操作符('),类似于Perl:

directoryListing = `ls /`
puts directoryListing # prints the contents of the root directory

如果你需要简单的东西,很方便。

你想要使用哪种方法取决于你想要完成什么;有关不同方法的更多细节,请查看文档。

这不是一个真正的答案,但也许有人会发现它有用:

在Windows上使用TK GUI时,您需要从rubyw调用shell命令,您总是会有一个烦人的CMD窗口弹出不到一秒钟。

为了避免这种情况,你可以使用:

WIN32OLE.new('Shell.Application').ShellExecute('ipconfig > log.txt','','','open',0)

or

WIN32OLE.new('WScript.Shell').Run('ipconfig > log.txt',0,0)

两者都将ipconfig输出存储在log.txt中,但是不会弹出窗口。

你需要在你的脚本中要求'win32ole'。

system(), exec()和spawn()都会在使用TK和rubyw时弹出恼人的窗口。

下面是我在OS X上的ruby脚本中使用的一个很酷的脚本(这样我就可以在切换离开窗口后启动脚本并获得更新):

cmd = %Q|osascript -e 'display notification "Server was reset" with title "Posted Update"'|
system ( cmd )

不确定shell命令。我使用以下命令将系统命令的输出捕获到变量val中:

val = capture(:stdout) do
  system("pwd")
end

puts val

缩短版本:

val = capture(:stdout) { system("pwd") }

捕获方法由active_support/core_ext/kernel/reporting.rb提供

类似地,我们也可以用:stderr捕获标准错误