如何从Ruby程序内部调用shell命令?然后如何将这些命令的输出返回到Ruby中?
当前回答
不确定shell命令。我使用以下命令将系统命令的输出捕获到变量val中:
val = capture(:stdout) do
system("pwd")
end
puts val
缩短版本:
val = capture(:stdout) { system("pwd") }
捕获方法由active_support/core_ext/kernel/reporting.rb提供
类似地,我们也可以用:stderr捕获标准错误
其他回答
这不是一个真正的答案,但也许有人会发现它有用:
在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时弹出恼人的窗口。
下面是一个基于“何时在Ruby中使用启动子进程的每种方法”的流程图。另请参见“欺骗应用程序,使其误以为标准输出是终端,而不是管道”。
backticks(')方法是在Ruby中调用shell命令最简单的方法。它返回shell命令的结果:
url_request = 'http://google.com'
result_of_shell_command = `curl #{url_request}`
给定像attrib这样的命令:
require 'open3'
a="attrib"
Open3.popen3(a) do |stdin, stdout, stderr|
puts stdout.read
end
我发现,虽然这种方法不像
system("thecommand")
or
`thecommand`
在反引号中,与其他方法相比,此方法的一个优点是 反勾号似乎不让我把我运行的命令/存储我想要运行的命令在一个变量中,而system(" command")似乎不让我得到输出,而这个方法让我做这两件事,它让我访问stdin, stdout和stderr独立。
参见“在ruby中执行命令”和ruby的Open3文档。
使用这里的答案和Mihai的答案链接,我组合了一个满足这些要求的函数:
整洁地捕获STDOUT和STDERR,因此当我的脚本从控制台运行时,它们不会“泄漏”。 允许参数作为数组传递给shell,因此不需要担心转义。 捕获命令的退出状态,以便在发生错误时显示出来。
作为奖励,当shell命令成功退出(0)并将任何内容放在STDOUT上时,该命令还将返回STDOUT。在这种情况下,它与system不同,后者在这种情况下只返回true。
代码如下。具体的函数是system_quiet:
require 'open3'
class ShellError < StandardError; end
#actual function:
def system_quietly(*cmd)
exit_status=nil
err=nil
out=nil
Open3.popen3(*cmd) do |stdin, stdout, stderr, wait_thread|
err = stderr.gets(nil)
out = stdout.gets(nil)
[stdin, stdout, stderr].each{|stream| stream.send('close')}
exit_status = wait_thread.value
end
if exit_status.to_i > 0
err = err.chomp if err
raise ShellError, err
elsif out
return out.chomp
else
return true
end
end
#calling it:
begin
puts system_quietly('which', 'ruby')
rescue ShellError
abort "Looks like you don't have the `ruby` command. Odd."
end
#output: => "/Users/me/.rvm/rubies/ruby-1.9.2-p136/bin/ruby"
推荐文章
- 是否可以在MiniTest中运行单个测试?
- 如何在Ruby中生成a和b之间的随机数?
- 查看PS命令的全部输出
- 确保一次只运行一个shell脚本实例的快速方法
- 无法安装gem -未能建立gem本地扩展-无法加载这样的文件——mkmf (LoadError)
- 如何在Ruby中创建文件
- 什么是Ruby文件。开放模式和选项?
- Ruby数组到字符串的转换
- 如何分割(块)一个Ruby数组成X元素的部分?
- Ruby中“or”和||的区别?
- Git与Mercurial仓库的互操作性
- 如何测试参数是否存在在轨道
- 如何在Makefile中设置子进程的环境变量
- 如何让“wc -l”打印没有文件名的行数?
- 有效地测试Linux上的端口是否打开?