Redhat and friends: Test for /etc/redhat-release, check contents
Debian: Test for /etc/debian_version, check contents
Mandriva and friends: Test for /etc/version, check contents
Slackware: Test for /etc/slackware-version, check contents
Etc. Generally speaking, check for /etc/*-release and /etc/*-version.
Edit: Found an old (1+ years) bash script of mine lying around that I must have cobbled together over the years (it has an impressive CVS log going back 6 years.) It might not work properly anymore as-is and I can't be bothered to find installed distros to test against, but it should provide you with a good starting point. It works fine on CentOS, Fedora and Gentoo. gyaresu tested it successfully on Debian Lenny.
#!/bin/bash
get_distribution_type()
{
local dtype
# Assume unknown
dtype="unknown"
# First test against Fedora / RHEL / CentOS / generic Redhat derivative
if [ -r /etc/rc.d/init.d/functions ]; then
source /etc/rc.d/init.d/functions
[ zz`type -t passed 2>/dev/null` == "zzfunction" ] && dtype="redhat"
# Then test against SUSE (must be after Redhat,
# I've seen rc.status on Ubuntu I think? TODO: Recheck that)
elif [ -r /etc/rc.status ]; then
source /etc/rc.status
[ zz`type -t rc_reset 2>/dev/null` == "zzfunction" ] && dtype="suse"
# Then test against Debian, Ubuntu and friends
elif [ -r /lib/lsb/init-functions ]; then
source /lib/lsb/init-functions
[ zz`type -t log_begin_msg 2>/dev/null` == "zzfunction" ] && dtype="debian"
# Then test against Gentoo
elif [ -r /etc/init.d/functions.sh ]; then
source /etc/init.d/functions.sh
[ zz`type -t ebegin 2>/dev/null` == "zzfunction" ] && dtype="gentoo"
# For Slackware we currently just test if /etc/slackware-version exists
# and isn't empty (TODO: Find a better way :)
elif [ -s /etc/slackware-version ]; then
dtype="slackware"
fi
echo $dtype
}
Note that this will probably only work correctly in Bash. You could rewrite it for other shells.
That being said, you might want to test for features, not for distributions. I'm not using this anymore simply because it became a maintenance burden. It's easier to rely on cross-distribution tools and solutions.
Conceptually, what it does is, in order:
Pull in a known, "common init script function" type of file. Those are distribution-specific. If it doesn't exist, skip to next distribution check.
Check the existence of a specific, known-to-exist, often-used and unlikely to be renamed function from that core script. We do that using the type Bash builtin. type -t returns function if that symbol is a function. We prepend zz to the output from type -t 2>/dev/null because if the name isn't defined the output string would be empty and we'd get a syntax error about a missing left hand to the == operator. If the name we just checked isn't a function, skip to next distribution check, otherwise we found the distribution type.
Finally, echo the distribution type so the function output can be easily used in a case .. esac block.
Edit in case you're trying to run this as a straight script: This script is supposed to get sourced or included from other scripts. It does not output anything on its own if you run it as-is. To test it, source it and then invoke the function, e.g.:
Don't try and make assumptions based on the distro as to what you can and cannot do, for that way lies madness (see also "User Agent detection"). Instead, detect whether what it is that you want to do is supported, and how it's done by whatever command or file location you want to use.
For example, if you wanted to install a package, you can detect whether you're on a Debian-like system or a RedHat-like system by checking for the existence of dpkg or rpm (check for dpkg first, because Debian machines can have the rpm command on them...). Make your decision as to what to do based on that, not just on whether it's a Debian or RedHat system. That way you'll automatically support any derivative distros that you didn't explicitly program in. Oh, and if your package requires specific dependencies, then test for those too and let the user know what they're missing.
Another example is fiddling with network interfaces. Work out what to do based on whether there's an /etc/network/interfaces file or an /etc/sysconfig/network-scripts directory, and go from there.
Yes, it's more work, but unless you want to remake all the mistakes that web developers have made over the past decade or more, you'll do it the smart way right from the start.
There is a standard out there known as the Linux Standard Base or LSB.
It defines that there should be a file called /etc/lsb-release or a program called lsb_release that will echo back information about your linux distro.
There is no cross-distribution way. However:
Etc. Generally speaking, check for
/etc/*-release
and/etc/*-version
.Edit: Found an old (1+ years) bash script of mine lying around that I must have cobbled together over the years (it has an impressive CVS log going back 6 years.) It might not work properly anymore as-is and I can't be bothered to find installed distros to test against, but it should provide you with a good starting point. It works fine on CentOS, Fedora and Gentoo. gyaresu tested it successfully on Debian Lenny.
Note that this will probably only work correctly in Bash. You could rewrite it for other shells.
That being said, you might want to test for features, not for distributions. I'm not using this anymore simply because it became a maintenance burden. It's easier to rely on cross-distribution tools and solutions.
Conceptually, what it does is, in order:
Edit in case you're trying to run this as a straight script: This script is supposed to get sourced or included from other scripts. It does not output anything on its own if you run it as-is. To test it, source it and then invoke the function, e.g.:
at the bash prompt.
Edit: Please note that this script does not require root privileges. I urge you not to run it as root. Shouldn't harm anything, but there's no need.
Found a link to a relevant mailing list post in the CVS log. Should be useful in unwrapping init script spaghetti.
Don't try and make assumptions based on the distro as to what you can and cannot do, for that way lies madness (see also "User Agent detection"). Instead, detect whether what it is that you want to do is supported, and how it's done by whatever command or file location you want to use.
For example, if you wanted to install a package, you can detect whether you're on a Debian-like system or a RedHat-like system by checking for the existence of dpkg or rpm (check for dpkg first, because Debian machines can have the rpm command on them...). Make your decision as to what to do based on that, not just on whether it's a Debian or RedHat system. That way you'll automatically support any derivative distros that you didn't explicitly program in. Oh, and if your package requires specific dependencies, then test for those too and let the user know what they're missing.
Another example is fiddling with network interfaces. Work out what to do based on whether there's an /etc/network/interfaces file or an /etc/sysconfig/network-scripts directory, and go from there.
Yes, it's more work, but unless you want to remake all the mistakes that web developers have made over the past decade or more, you'll do it the smart way right from the start.
You can find the kernel version by running
uname -a
, finding the distro version is dependant on the distro.On Ubuntu and some other OS' you can run
lsb_release -a
or read /etc/lsb_releaseDebian stores the version in /etc/debian_version
Most distro's have a unique method of determining the particular distribution.
For example:
There is a standard out there known as the Linux Standard Base or LSB. It defines that there should be a file called /etc/lsb-release or a program called lsb_release that will echo back information about your linux distro.
code: http://hg.python.org/cpython/file/2.7/Lib/platform.py
In addition to the other answers: If you just want to parse one file, most distros personalize the tty login via /etc/issue e.g.:
And yes I know it's suboptimal. :)
facter is a handy tool for this sort of discovery, although it probably uses some of the methods detailed above, and requires Ruby.
All you need to do is type
uname -a
at your favorite shell. That will print out the kernel name and version.You can also get the version by
o/p:
I've found that
cat /etc/*release*
almost always works.