如何找到 Ruby 程序运行的操作系统?

我希望我的 Ruby 程序可以在 Mac 和 Windows 上做不同的事情。如何查明程序在哪个系统上运行?

41312 次浏览

Either

irb(main):002:0> require 'rbconfig'
=> true
irb(main):003:0> Config::CONFIG["arch"]
=> "i686-linux"

or

irb(main):004:0> RUBY_PLATFORM
=> "i686-linux"

Use the RUBY_PLATFORM constant, and optionally wrap it in a module to make it more friendly:

module OS
def OS.windows?
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
end


def OS.mac?
(/darwin/ =~ RUBY_PLATFORM) != nil
end


def OS.unix?
!OS.windows?
end


def OS.linux?
OS.unix? and not OS.mac?
end


def OS.jruby?
RUBY_ENGINE == 'jruby'
end
end

It is not perfect, but works well for the platforms that I do development on, and it's easy enough to extend.

Try the Launchy gem (gem install launchy):

require 'launchy'
Launchy::Application.new.host_os_family # => :windows, :darwin, :nix, or :cygwin
require 'rbconfig'
include Config


case CONFIG['host_os']
when /mswin|windows/i
# Windows
when /linux|arch/i
# Linux
when /sunos|solaris/i
# Solaris
when /darwin/i
#MAC OS X
else
# whatever
end

When I just need to know if it is a Windows or Unix-like OS it is often enough to

is_unix = is_win = false
File::SEPARATOR == '/' ? is_unix = true : is_win = true

(Warning: read @Peter Wagenet's comment ) I like this, most people use rubygems, its reliable, is cross platform

irb(main):001:0> Gem::Platform.local
=> #<Gem::Platform:0x151ea14 @cpu="x86", @os="mingw32", @version=nil>
irb(main):002:0> Gem::Platform.local.os
=> "mingw32"

update use in conjunction with "Update! Addition! Rubygems nowadays..." to mitigate when Gem::Platform.local.os == 'java'

I have a second answer, to add more options to the fray. The os rubygem, and their github page has a related projects list.

require 'os'


>> OS.windows?
=> true   # or OS.doze?


>> OS.bits
=> 32


>> OS.java?
=> true # if you're running in jruby.  Also OS.jruby?


>> OS.ruby_bin
=> "c:\ruby18\bin\ruby.exe" # or "/usr/local/bin/ruby" or what not


>> OS.posix?
=> false # true for linux, os x, cygwin


>> OS.mac? # or OS.osx? or OS.x?
=> false

We have been doing pretty good so far with the following code

  def self.windows?
return File.exist? "c:/WINDOWS" if RUBY_PLATFORM == 'java'
RUBY_PLATFORM =~ /mingw32/ || RUBY_PLATFORM =~ /mswin32/
end


def self.linux?
return File.exist? "/usr" if RUBY_PLATFORM == 'java'
RUBY_PLATFORM =~ /linux/
end


def self.os
return :linux if self.linux?
return :windows if self.windows?
nil
end

Update! Addition! Rubygems nowadays ships with Gem.win_platform?.

Example usages in the Rubygems repo, and this one, for clarity:

def self.ant_script
Gem.win_platform? ? 'ant.bat' : 'ant'
end

For something readily accessible in most Ruby installations that is already somewhat processed for you, I recommend these:

  1. Gem::Platform.local.os #=> eg. "mingw32", "java", "linux", "cygwin", "aix", "dalvik" (code)
  2. Gem.win_platform? #=> eg. true, false (code)

Both these and every other platform checking script I know is based on interpreting these underlying variables:

  1. RbConfig::CONFIG["host_os"] #=> eg. "linux-gnu" (code 1, 2)
  2. RbConfig::CONFIG["arch"] #=> eg. "i686-linux", "i386-linux-gnu" (passed as parameter when the Ruby interpreter is compiled)
  3. RUBY_PLATFORM #=> eg. "i386-linux-gnu", "darwin" - Note that this returns "java" in JRuby! (code)
    • These are all Windows variants: /cygwin|mswin|mingw|bccwin|wince|emx/
  4. RUBY_ENGINE #=> eg. "ruby", "jruby"

Libraries are available if you don't mind the dependency and want something a little more user-friendly. Specifically, OS offers methods like OS.mac? or OS.posix?. Platform can distinguish well between a variety of Unix platforms. Platform::IMPL will return, eg. :linux, :freebsd, :netbsd, :hpux. sys-uname and sysinfo are similar. utilinfo is extremely basic, and will fail on any systems beyond Windows, Mac, and Linux.

If you want more advanced libraries with specific system details, like different Linux distributions, see my answer for Detecting Linux distribution in Ruby.

Using the os gem, when loading different binaries for IMGKit

# frozen_string_literal: true
IMGKit.configure do |config|
if OS.linux? && OS.host_cpu == "x86_64"
config.wkhtmltoimage =
Rails.root.join("bin", "wkhtmltoimage-linux-amd64").to_s
elsif OS.mac? && OS.host_cpu == "x86_64"
config.wkhtmltoimage =
Rails.root.join("bin", "wkhtmltoimage-macos-amd64").to_s
else
puts OS.report
abort "You need to add a binary for wkhtmltoimage for your OS and CPU"
end
end