Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Say I am logged into a remote system, how can I know what it's running? On most modern Linuxes (Linuces?), you have the lsb_release command:

$ lsb_release -ic    
Distributor ID: LinuxMint
Codename:       debian

Which as far as I can tell just gives the same info as /etc/lsb-release. What if that file is not present? I seem to recall that the lsb_release command is relatively new so what if I have to get the OS of an older system?

In any case, lsb stands for Linux Standard Base so I am assuming it won't work on non-Linux Unices. As far as I know, there is no way of getting this information from uname so how can I get this on systems that do not use lsb_release?

share|improve this question
1  
unix.stackexchange.com/questions/6345/… for Linux. uname -s should be enough outside Linux (expect possibly for the BSDs). –  Mat Sep 24 '13 at 18:51
    
Have you checked out facter? facter operatingsystem should do what you want on all the systems facter was made to work with. –  Joseph R. Sep 24 '13 at 18:53
    
@JosephR. looks good but is not installed by default. –  terdon Sep 24 '13 at 18:54
1  
I pasted the facter code that gets the operating system name on pastebin. Find it here. It checks many different files to get the name reliably. –  Joseph R. Sep 24 '13 at 19:01
    
@JosephR. wow, that's a lot of files. I'll port that to bash when I get the chance, that should be portable enough. Thanks! –  terdon Sep 24 '13 at 19:19

11 Answers 11

up vote 28 down vote accepted

lsb_release -a is likely going to be your best option for finding this information out, and being able to do so in a consistent way.

History of LSB

The lsb in that command stands for the project Linux Standards Base which is an umbrella project sponsored by the Linux Foundation to provide generic methods for doing basic kinds of things on various Linux distros.

The project is voluntary and vendors can participate within the project as just a user and also as facilitators of the various specifications around different modules that help to drive standardization within the different Linux distributions.

excerpt from the charter

The LSB workgroup has, as its core goal, to address these two concerns. We publish a standard that describes the minimum set of APIs a distribution must support, in consultation with the major distribution vendors. We also provide tests and tools which measure support for the standard, and enable application developers to target the common set. Finally, through our testing work, we seek to prevent unnecessary divergence between the distributions.

Useful links related to LSB

Criticisms

There are a number of problems with LSB that make it problematic for distros such as Debian. The forced usage of RPM being one. See the Wikipedia article for more on the matter.

Novell

If you search you'll possible come across a fairly dated looking page titled: Detecting Underlying Linux Distro from Novell. This is one of the few places I"ve seen an actual list that shows several of the major distros and how you can detect what underlying one you're using.

excerpt

Novell SUSE         /etc/SUSE-release
Red Hat             /etc/redhat-release, /etc/redhat_version
Fedora              /etc/fedora-release
Slackware           /etc/slackware-release, /etc/slackware-version
Debian              /etc/debian_release, /etc/debian_version,
Mandrake            /etc/mandrake-release
Yellow dog          /etc/yellowdog-release
Sun JDS             /etc/sun-release
Solaris/Sparc       /etc/release
Gentoo              /etc/gentoo-release
UnitedLinux         /etc/UnitedLinux-release
ubuntu              /etc/lsb-release

This same page also includes a handy script which attempts to codify for the above using just vanilla uname commands, and the presence of one of the above files.

NOTE: This list is dated but you could easily drop the dated distros such as Mandrake from the list and replace them with alternatives. This type of a script might be one approach if you're attempting to support a large swath of Solaris & Linux variants.

Linux Mafia

More searching will turn up the following page maintained on Linuxmafia.com, titled: /etc/release equivalents for sundry Linux (and other Unix) distributions. This is probably the most exhaustive list to date that I've seen. You could codify this list with a case/switch statement and include it as part of your software distribution.

In fact there is a script at the bottom of that page that does exactly that. So you could simply download and use the script as 3rd party to your software distribution.

script

#!/bin/sh
# Detects which OS and if it is Linux then it will detect which Linux
# Distribution.

OS=`uname -s`
REV=`uname -r`
MACH=`uname -m`

GetVersionFromFile()
{
    VERSION=`cat $1 | tr "\n" ' ' | sed s/.*VERSION.*=\ // `
}

if [ "${OS}" = "SunOS" ] ; then
    OS=Solaris
    ARCH=`uname -p` 
    OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"
elif [ "${OS}" = "AIX" ] ; then
    OSSTR="${OS} `oslevel` (`oslevel -r`)"
elif [ "${OS}" = "Linux" ] ; then
    KERNEL=`uname -r`
    if [ -f /etc/redhat-release ] ; then
        DIST='RedHat'
        PSUEDONAME=`cat /etc/redhat-release | sed s/.*\(// | sed s/\)//`
        REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
    elif [ -f /etc/SuSE-release ] ; then
        DIST=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
        REV=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
    elif [ -f /etc/mandrake-release ] ; then
        DIST='Mandrake'
        PSUEDONAME=`cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//`
        REV=`cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//`
    elif [ -f /etc/debian_version ] ; then
        DIST="Debian `cat /etc/debian_version`"
        REV=""

    fi
    if [ -f /etc/UnitedLinux-release ] ; then
        DIST="${DIST}[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
    fi

    OSSTR="${OS} ${DIST} ${REV}(${PSUEDONAME} ${KERNEL} ${MACH})"

fi

echo ${OSSTR}

NOTE: This script should look familiar, it's an up to date version of the Novell one!

Legroom script

Another method I've seen employed is to roll your own script, similar to the above Novell method but making use of LSB instead. This article titled: Generic Method to Determine Linux (or UNIX) Distribution Name, shows one such method.

# Determine OS platform
UNAME=$(uname | tr "[:upper:]" "[:lower:]")
# If Linux, try to determine specific distribution
if [ "$UNAME" == "linux" ]; then
    # If available, use LSB to identify distribution
    if [ -f /etc/lsb-release -o -d /etc/lsb-release.d ]; then
        export DISTRO=$(lsb_release -i | cut -d: -f2 | sed s/'^\t'//)
    # Otherwise, use release info file
    else
        export DISTRO=$(ls -d /etc/[A-Za-z]*[_-][rv]e[lr]* | grep -v "lsb" | cut -d'/' -f3 | cut -d'-' -f1 | cut -d'_' -f1)
    fi
fi
# For everything else (or if above failed), just use generic identifier
[ "$DISTRO" == "" ] && export DISTRO=$UNAME
unset UNAME

This chunk of code could be included into a system's /etc/bashrc or some such file which would then set the environment variable $DISTRO.

gcc

Believe it or not another method is to make use of gcc. If you query the command gcc --version you'll get the distro that gcc was built for, which is invaribly the same as the system it's running on.

Fedora 14

$ gcc --version
gcc (GCC) 4.5.1 20100924 (Red Hat 4.5.1-4)
Copyright (C) 2010 Free Software Foundation, Inc.

CentOS 5.x

$ gcc --version
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-54)
Copyright (C) 2006 Free Software Foundation, Inc.

CentOS 6.x

$ gcc --version
gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)
Copyright (C) 2010 Free Software Foundation, Inc.

Ubuntu 12.04

$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.

TL;DR;

So which one should I use? I would tend to go with lsb_release -a for any Linux distributions that I would frequent (RedHat, Debian, Ubuntu, etc.). For situations where you're supporting systems that don't provide lsb_release I'd roll my own as part of the distribution of software that I'm providing, similar to one of the above scripts.

UPDATE #1: Follow-up with SuSE

In speaking with @Nils in the comments below it was determined that for whatever reason, SLES11 appeared to drop LSB from being installed by default. It was only an optional installation, which seemed counter for a package that provides this type of key feature.

So I took the opportunity to contact someone from the OpenSuSE project to get a sense of why.

excerpt of email

Hi Rob,

I hope you don't mind me contacting you directly but I found your info here: 
https://en.opensuse.org/User:Rjschwei. I participate on one of the StackExchange 
sites, Unix & Linux and a question recently came up regarding the best option 
for determining the underlying OS.

http://unix.stackexchange.com/questions/92199/how-can-i-reliably-get-the-operating-systems-name/92218?noredirect=1#comment140840_92218

In my answer I suggested using lsb_release, but one of the other users mentioned 
that this command wasn't installed as part of SLES11 which kind of surprised me. 
Anyway we were looking for some way to confirm whether this was intentionally 
dropped from SLES or it was accidental.

Would you know how we could go about confirming this one way or another?

Thanks for reading this, appreciate any help and/or guidance on this.

-Sam Mingolelli
http://unix.stackexchange.com/users/7453/slm

Here's Rob's response

Hi,

On 10/01/2013 09:31 AM, Sam Mingo wrote:
- show quoted text -

lsb_release was not dropped in SLES 11. SLES 11 is LSB certified. However, it 
is not installed by default, which is consistent with pretty much every other
distribution. The lsb_release command is part of the lsb-release package.

At present almost every distribution has an entry in /etc such as 
/etc/SuSE-release for SLES and openSUSE. Since this is difficult for ISVs and 
others there is a standardization effort going on driven by the convergence to 
systemd. The standard location for distribution information in the future will 
be /etc/os-release, although Ubuntu will probably do something different.

HTH,    
Robert

--  Robert Schweikert                           MAY THE SOURCE BE WITH YOU    
SUSE-IBM Software Integration Center                   LINUX    
Tech Lead    
Public Cloud Architect 
share|improve this answer
    
Note: Just did a quick check on machines with AIX and SunOS. They don't seem to have lsb_release installed (and after all, this is Unix not Linux stack). Problem with gcc is that some ppl now start using clang. Also you can never be sure which gcc was used to build (on systems I work with there are at least few versions on each). So my vote goes to Python solution as it seems to be installed now everywhere by default. –  elmo Sep 25 '13 at 9:16
    
@elmo - yes LSB is Linux Standard Base, so I wouldn't expect either AIX or SunOS to have it. My experience with SunOS is 15+ years, and the majority of vendors whose software I dealt with would usually provide there own shell script similar to the ones I referenced above. Until Solaris 11, Python was not an option. And this is what makes it a difficult nut to crack. If you provide software that needs to run on Solaris 9, 10, 11, AIX, and a couple of Linux distros (SUSE, Ubntu, and RHEL) what do you do? Python is not an option, so you're left with a hand coded shell script. –  slm Sep 25 '13 at 9:29
    
@elmo - gcc though, an option, doesn't appear to be that appealing to me either. It seems wrought with too many problems, I was demonstrating it merely as an option. –  slm Sep 25 '13 at 9:31
    
@elmo - look at the code behind that function, hg.python.org/cpython/file/2.7/Lib/platform.py#l259. Big surprise it's using LSB! –  slm Sep 25 '13 at 9:34
    
@slm: I have access to machine with SunOS 5.10 (which I assume is 10 in your list - I am not that familiar with version numbers/conventions of Sun) and it does have a Python. I have access to machine with AIX 7 and it does have Python. Linux machines obviously have it also. So still Python looks like most portable choice. As for Sun below 10 I am not sure why it wouldn't allow Python to be installed (admittedly current install is lacking i.e. ncurses and ctypes, so who knows). As for Python using LSB it is not surprising at all for Linux if it is default approach. –  elmo Sep 26 '13 at 10:49

Since you probably won't be able to install facter on a remote server, you can mimic what it does to find the OS name. The Ruby code for the operatingsystem fact can be found here on pastebin. Basically, it looks through the different *-release files and others to determine the OS name.

Some of the files it looks at:

/etc/debian_version
/etc/gentoo-release
/etc/fedora-release
/etc/mandriva-release
/etc/mandrake-release
/etc/meego-release
/etc/arch-release
/etc/oracle-release
/etc/enterprise-release
/etc/ovs-release
/etc/vmware-release
/etc/redhat-release
/etc/SuSE-release
/etc/bluewhite64-version
/etc/slamd64-version
/etc/slackware-version
/etc/alpine-release
/etc/system-release
/etc/centos-release

I'm sorry if you find duplicates in this list, I produced it quickly with grep. Should be fairly easy (albeit a bit tedious) to port this to a POSIX shell script.

share|improve this answer
3  
"I'm sorry if you find duplicates in this list, I produced it quickly with grep." ... | uniq? –  new123456 Sep 24 '13 at 23:12
    
@new123456 Right. Thanks. The key word here is "quickly" :) –  Joseph R. Sep 24 '13 at 23:26
    
Sorry about unaccepting this but @slm's answer is just too comprehensive to ignore :). –  terdon Sep 25 '13 at 1:36
    
@terdon No worries. It's your question :) –  Joseph R. Sep 25 '13 at 6:50
    
what about /etc/os-release ? –  Yauhen Yakimovich Jul 24 at 15:57

You can't reliably get the distro name from a single command across all distros. Some are available via /etc/*-release and others are available via the 'lsb-release' command.

share|improve this answer
    
Thanks but neither is a help when it comes to Unix or any other non-Linux *nix. –  terdon Sep 24 '13 at 19:19

In case you have python installed (doesn't matter whether Python 3 or Python 2), you can find out the distribution name without reinventing the wheel:

python -c "import platform;print(platform.linux_distribution()[0])"
share|improve this answer
    
If you are tempted to use this option make sure your OS is supported: hg.python.org/cpython/file/2.7/Lib/platform.py#l259. If not you can add more to the list: coderwall.com/p/cwrenq –  slm Sep 25 '13 at 9:37

/etc/issue should contain the release information. I am fairly certain I've seen it on Solaris systems. Here is the file from a modern Debian system:

$ cat /etc/issue
Debian GNU/Linux 7 \n \l

$ 

/etc/issue is also mentioned in the FHS (which isn't solely for Linux systems), although it is "optional."

share|improve this answer
    
Ah, that's a good suggestion, +1. It might not always work though The file /etc/issue is a text file which contains a message or system identification to be printed before the login prompt. It seems to be up to the sysadmin to write whatever he/she desires. –  terdon Sep 24 '13 at 18:49
1  
/etc/issue is completely unreliable. (I've see systems in version X.Y with an /etc/issue banner saying they were Y.Z following bad patch management. It can contain absolutely anything.) –  Mat Sep 24 '13 at 18:52
    
It is recommended to fill that file with. legal stuff like who is allowed to login. –  Nils Sep 24 '13 at 19:06
    
Yep, that's the problem with optional :) Many distributions (including non-Linux ones) fill it out by default, though. It's pretty free-form, so there's nothing to easily parse. –  drewbenn Sep 24 '13 at 19:09
    
@Nils recommended by who? The man page doesn't say anything about legal info, just "...system identification to be printed before the login prompt." –  drewbenn Sep 24 '13 at 19:24

SNMP is an ubiquitous enough protocol so as to be found in many different kinds of GNU/Linux distributions and UNIX systems.

The system.sysDescr.0 object in the SNMPv2-MIB can help you find out which OS you are contacting, provided there's an SNMP daemon running in the target system:

Description

A textual description of the entity. This value should include the full name and version identification of the system's hardware type, software operating-system, and networking software.

Status: current

Access: read-only

The snmpget(1) manpage explains how to retrieve this value with examples.

share|improve this answer
    
Drawback is that this is a static string that is not automatically maintained. –  Nils Sep 24 '13 at 19:17

Since there is no common way to do so, we defined an release-string via the snmp exec-command.

The task of that command is to print out distro and the current major/minor version of the os.

On RH and clones we parse /etc/redhat-release, on SuSe SuSe-release...

share|improve this answer
    
Who is 'we'? And how about Unix? –  terdon Sep 24 '13 at 19:15
    
@terdon we is our team at work. On Unix you can do the same if the corresponding extension is compiled into snmpd. –  Nils Sep 24 '13 at 19:39
    
Ah, I thought you were a part of some standards group :) –  terdon Sep 24 '13 at 19:42
    
@terdon You start developing site-standards when you have to manage more than 80 servers. We developed this method so we could monitor wether the os is outdated (EoL minor or even major number) –  Nils Sep 24 '13 at 19:50

From what I've managed to glean from this thread you should be able to get the info from damn-near any system using:

if which lsb_release &>> /dev/null; then
    lsb_release -a
elif [ -r /etc/issue ]; then
    cat /etc/issue
else
    ls /etc/ | grep -e '[_-]release$' -e '[_-]version$' | xargs -I % -n 1 cat /etc/%
fi
share|improve this answer
1  
don't parse output of ls! –  heinrich5991 Sep 24 '13 at 23:17
    
@heinrich5991 why not? –  Sammitch Sep 24 '13 at 23:31

In this page it's said that there are differents commands to find out. As far as i googled, there is not a single commando to find it out as it is a Distro dependency.

share|improve this answer
    
Thanks but those are either Linux specific (all the lsb ones) or print out the kernel version which may well be Linux specific again but in any case will not always be branded with the OS name. –  terdon Sep 24 '13 at 18:50

I used this shell command to get a string indicating Linux distribution:

for f in $(find /etc -type f -maxdepth 1 \( ! -wholename /etc/os-release ! -wholename /etc/lsb-release -wholename /etc/\*release -o -wholename /etc/\*version \) 2> /dev/null); do echo ${f:5:${#f}-13}; done;

this command is based on answers of Joseph R. and slm.

It just seeks for files like /etc/{osname}-release or /etc/{osname}_version and prints particular os name.

It worked in

  • CentOS (centos)
  • RedHat (redhat)
  • Debian (debian)
  • Arch (arch)
  • OpenSUSE (OpenSUSE)
  • Fedora (fedora)
  • Ubuntu (debian)
share|improve this answer
    
Wouldn't for f in /etc/*{_version,...*-release}; do [ -f "$f" ] && echo ${f:5:${#f}-13} ; done work equally well on all of them? I don't understand why you would first find all files in /etc. –  terdon May 8 at 13:43
    
Thank you for your feedback, terdon, but your command gives 0 lines in at least Cent OS and Fedora –  starfury May 13 at 12:05

If a situation called for it, you could find out remotely using snmpwalk [or the SNMP protocal in general]. An example is below:

snmpwalk -Os -c <snmp community string> -v1 <hostname> sysDescr.0

OUPUT: sysDescr.0 = STRING: Linux example.hostname.com 2.6.32-358.23.2.el6.x86_64 #1 SMP Sat Sep 14 05:32:37 EDT 2013 x86_64

The key to the reliability is whether SNMP is setup correctly in your environment, all hosts have snmp running with proper community strings setup.

share|improve this answer
    
What's snpwalk? Where can I find it? Also, that just prints "Linux", no distribution information (which is what I want, uname can give me Linux). Does it work on non-Linux OSs? On UNIX say, or BSD or OSX? –  terdon Nov 13 at 14:52
    
snmpwalk is a Linux command line utility. It doesn't just print "Linux" it also prints the kernel version which is really the only thing you need. If SNMP is configured on your other hosts, whether it is UNIX, BSD, OSX, snmpwalk will work as it is a standard (v1|v2c|v3), and it will even work across the water on Windows hosts as well. See also snmpget or snmpgetnext. –  xpro-fedtest Nov 13 at 16:30
    
Sounds good but could you please edit your answer and explain where we can find it. It's not int he Debian repos for example. Also, please explain what it gives that uname -a doesn't and how it can tell me the name of the distribution which is what this question is about. Anyway, even assuming it can return this info, seeing as it's a non-standard utility and needs to be installed, I'm not sure it would be useful here. The idea is to log on to a remote system and find out the OS (including distribution if it's Linux). –  terdon Nov 13 at 16:42

protected by slm Jun 9 at 11:25

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.