Reputation: 13122
I can check the operating system of the platform that is running my Ruby code in a several ways:
RUBY_PLATFORM
: https://stackoverflow.com/a/171011/462015RbConfig::CONFIG['host_os']
: https://stackoverflow.com/a/13586108/462015Is it possible to know what Linux distribution is running? For example a Debian based or a Red Hat based distribution.
Upvotes: 7
Views: 2453
Reputation: 8403
The question does not indicate the purpose. If the purpose is to determine if a distribution-specific command is available, this might be an appropriate answer.
The Ruby standard library provides find_executable. You can use find_executable
and find_executable0
to check the package manager.
For example, to detect Debian, or derivatives such as Ubuntu, just check for the existence of dpkg
.
require 'mkmf'
MakeMakefile::Logging.instance_variable_set(:@logfile, nil)
puts "Debian compatible" if find_executable0 'dpkg'
To detect Ubuntu, or a derivative such as Mint, check for apt
.
require 'mkmf'
MakeMakefile::Logging.instance_variable_set(:@logfile, nil)
puts "Ubuntu compatible" if find_executable0 'apt'
Note that find_executable
outputs a message, which you might not want. find_executable0
performs the same task, without generating the message:
irb(main):006> require 'mkmf'
=> false
irb(main):007> find_executable 'dpkg'
checking for dpkg... yes
=> "/usr/bin/dpkg"
irb(main):008> find_executable0 'dpkg'
=> "/usr/bin/dpkg"
Upvotes: 0
Reputation: 843
A Linux distribution is a collection of software, usually distinguishable by their package manager, window system, window manager, and desktop environment. That's a lot of interchangeable parts. If a system keeps the package manager, but changes the window system and desktop environment, do we call it a new distribution? There's no definitive answer, so various tools will give slightly different answers.
Train has a whole hierarchy of distribution families and may be the most sophisticated of the bunch. A quick comparison of Train and Ohai is here. It's designed to be run over a network connection, but works fine locally, too, as shown here:
# gem install train
Train.create('local').connection.os[:name] #=> eg. "centos", "linuxmint"
Train.create('local').connection.os[:family] #=> eg. "redhat", "debian"
Facter's osfamily fact returns, eg. "Debian" for Ubuntu. With Facter, the general form for retrieving facts is Facter[factname].value
.
# gem install facter
require 'facter'
puts Facter['osfamily'].value
Ohai's platform_family
fact returns, eg. "debian" for Ubuntu and "rhel" for CentOS. With Ohai, the general form for retrieving facts is node[factname]
.
# gem install ohai
node['platform'] #=> eg. "ubuntu" or "mint"
node['platform_family'] #=> eg. "debian" for Ubuntu and Mint
Platform retrieves some basic data, and can distinguish well between a variety of Unix platforms. However, it doesn't handle different distributions of Linux at all. Platform::IMPL
will return :freebsd, :netbsd, :hpux, etc., but all Linux distros are just :linux. sys-uname and sysinfo are similar. utilinfo is even more basic, and will fail on any systems beyond Windows, Mac, and Linux.
Upvotes: 1
Reputation:
As pointed above in the comment section, it seems that there is no sure "works in every distribution" way of doing this. What follows is what I've used to detect what kind of an environment a script is being run:
def linux_variant
r = { :distro => nil, :family => nil }
if File.exists?('/etc/lsb-release')
File.open('/etc/lsb-release', 'r').read.each_line do |line|
r = { :distro => $1 } if line =~ /^DISTRIB_ID=(.*)/
end
end
if File.exists?('/etc/debian_version')
r[:distro] = 'Debian' if r[:distro].nil?
r[:family] = 'Debian' if r[:variant].nil?
elsif File.exists?('/etc/redhat-release') or File.exists?('/etc/centos-release')
r[:family] = 'RedHat' if r[:family].nil?
r[:distro] = 'CentOS' if File.exists?('/etc/centos-release')
elsif File.exists?('/etc/SuSE-release')
r[:distro] = 'SLES' if r[:distro].nil?
end
return r
end
This is not a complete solution to handle every GNU/Linux distribution on earth. Far from it, actually. For example it makes no distinction between OpenSUSE and SUSE Linux Enterprise Server, though they are two quite different beasts. Besides, it's quite a spaghetti even with just a few distros. But it might be something one might be able to build on.
You can find a more complete example of distribution detection from the source code of Facter which is used, among other things, to feed facts to a configuration management system Puppet.
Upvotes: 3