如何从Ruby程序内部调用shell命令?然后如何将这些命令的输出返回到Ruby中?
当前回答
下面是我在OS X上的ruby脚本中使用的一个很酷的脚本(这样我就可以在切换离开窗口后启动脚本并获得更新):
cmd = %Q|osascript -e 'display notification "Server was reset" with title "Posted Update"'|
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中使用启动子进程的每种方法”的流程图。另请参见“欺骗应用程序,使其误以为标准输出是终端,而不是管道”。
最简单的方法是:
reboot = `init 6`
puts reboot
上面的答案已经非常棒了,但是我真的很想分享下面的总结文章:“在Ruby中运行Shell命令的6种方法”
基本上,它告诉我们:
# exec内核:
exec 'echo "hello $HOSTNAME"'
System和$?:
system 'false'
puts $?
Backticks ():
today = `date`
IO # execlp:
IO.popen("date") { |f| puts f.gets }
Open3#popen3—stdlib:
require "open3"
stdin, stdout, stderr = Open3.popen3('dc')
Open4#popen4—一个宝石:
require "open4"
pid, stdin, stdout, stderr = Open4::popen4 "false" # => [26327, #<IO:0x6dff24>, #<IO:0x6dfee8>, #<IO:0x6dfe84>]
在这些机制之间进行选择时需要考虑的一些事情是:
你只是想要stdout还是 也需要stderr ?甚至 分离出来吗? 你的产出有多大?你想要 将整个结果保存在内存中? 你想读一些你的吗 在子进程静止时输出 跑步吗? 你需要结果代码吗? 你需要一个Ruby对象吗 表示流程并允许您 按需杀死它?
您可能需要简单的反撇号(' ')、system()和IO。popen到成熟的Kernel.fork/Kernel。执行IO。pipe和IO.select。
如果子进程执行时间过长,您可能还想在混合过程中加入超时。
不幸的是,这在很大程度上取决于情况。