48

I know the commands to check the name of the Linux machine running on my machine. For example:

Ubuntu

cat /etc/version

CentOS

cat /etc/issue

How do I get the output from the terminal and compare to see if it is UBUNTU or CENTOS and perform the following commands?

apt-get install updates 

or

yum update

Ubuntu 14.04

cat /etc/issue

13 Answers 13

64

Unfortunately, there is no surefire, simple way of getting the distribution name. Most major distros are moving towards a system where they use /etc/os-release to store this information. Most modern distributions also include the lsb_release tools but these are not always installed by default. So, here are some approaches you can use:

  1. Use /etc/os-release

    awk -F= '/^NAME/{print $2}' /etc/os-release
    
  2. Use the lsb_release tools if available

    lsb_release -d | awk -F"\t" '{print $2}'
    
  3. Use a more complex script that should work for the great majority of distros:

    # 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
    
  4. Parse the version info of gcc if installed:

    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.
    

    Ubuntu 14.04

    $ gcc --version
    gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
    Copyright (C) 2013 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    

This has basically been directly copied from @slm's great answer to my question here.

| improve this answer | |
  • "Unfortunately, there is no surefire, simple way of getting the distribution name." <— This is not the case at all. Sylvain Pineau, for example, exhibited a trivial one-liner reliably querying the current platform type by deferring to Python – which comes preinstalled on most platforms (including Ubuntu). Shell scripts should never attempt to manually query platform metadata with low-level, non-portable tests of the sort implemented in this answer. – Cecil Curry Aug 17 '17 at 3:29
  • Gawk is not installed in Debian by default. – Ville Laitila Apr 20 '18 at 8:02
  • @VilleLaitila I'm afraid that's not relevant here since this site is only about Ubuntu. But there's nothing gawk-specific here, so awk or mawk or ay other implementation would work just as well. – terdon Apr 20 '18 at 8:05
  • Even more specific using lsb_release: lsb_release -d | awk -F"\t" '{print $2}' | awk -F " " '{print $1}' – NerdOfCode Nov 4 '18 at 14:27
  • @NerdOfCode if you just want the release number, do lsb_release -d | awk '{print $3}' or grep -oP 'VERSION="\K\S+' /etc/os-release, no need for the double pipe to awk. – terdon Nov 5 '18 at 9:21
26

You don't need bash to do such task, and I'd suggest using a high-level approach to avoid dealing with files like /etc/version and /etc/issue (I don't have /etc/version on 13.10).

So my recommendation is to use this command instead:

python -mplatform | grep -qi Ubuntu && sudo apt-get update || sudo yum update

python platform module will work on both systems, the rest of the command will check if Ubuntu is returned by python and run apt-get else yum.

| improve this answer | |
  • add -i to grep may help. – coanor Mar 28 '16 at 3:12
  • This does not seem to work anymore for Ubuntu 20.04 (I got Linux-5.4.0-26-generic-x86_64-with-glibc2.29). – wilsonzlin Apr 25 at 5:17
  • @wilsonzlin This still works on Python 2.7 but not on Python3. – Jonathan May 27 at 10:42
8

Here's a simple answer that I find works across all versions of Ubuntu / CentOS / RHEL by the mere presence of the files (not failsafe of course if someone is randomly dropping /etc/redhat-release on your Ubuntu boxes, etc):

if [ -f /etc/redhat-release ]; then
  yum update
fi

if [ -f /etc/lsb-release ]; then
  apt-get update
fi
| improve this answer | |
  • on my ubuntu there is no /etc/lsb-release – noonex Nov 14 '16 at 8:17
  • 3
    I'm not going to -1, but this answer is not correct in at least one case: /etc/lsb-release exists on CloudLinux (CentOS) 6.8 so it will return both yum and apt-get. – dhaupin Nov 28 '16 at 16:56
  • Ubuntu 18.04 has /etc/lsb-release in package base-files and /usr/bin/lsb_release in package lsb-release. – Markus Kuhn Dec 7 '19 at 13:30
  • Manjaro has /etc/lsb-release and does not have apt-get – VanDavv May 28 at 10:19
7

Check for Ubuntu in the kernel name:

if [  -n "$(uname -a | grep Ubuntu)" ]; then
    sudo apt-get update && sudo apt-get upgrade 
else
    yum update
fi  
| improve this answer | |
5

Use Chef for these tasks .;-)

In Chef, you can use the platform? method:

if platform?("redhat", "centos", "fedora")
  # Code for only Red Hat Linux family systems.
end

Or:

if platform?("ubuntu")
  # Code for only Ubuntu systems
end

Or:

if platform?("ubuntu")
  # Do Ubuntu things
end

Or:

if platform?("freebsd", "openbsd")
  # Do BSD things
end
| improve this answer | |
  • 1
    While demonstrably superior to low-level shell-centric fragile non-solutions (e.g., lsb_release, /etc/os-release), this solution has the distinct disadvantage of requiring Chef – a heavyweight Infrastructure as Code (IaC) framework not installed by default on most platforms and requiring use of its own domain-specific language (DSL). In short, most users probably just want to defer to Python, which is installed by default on most platforms (including Ubuntu) and interfaces well with shell scripting. – Cecil Curry Aug 17 '17 at 3:22
4
 apt-get -v &> /dev/null && apt-get update
 which yum &> /dev/null && yum update

if there are only two distro, then you can make it shorter:

apt-get -v &> /dev/null && apt-get update || yum update

somehow yum -v return non-zero in CentOS so use which instead,
of course you should consider scenario if there is no which installed.

| improve this answer | |
2

The following script should tell if it is Ubuntu. If it is not and the only other option you have is CentOS, you should have it in an else clause:

dist=`grep DISTRIB_ID /etc/*-release | awk -F '=' '{print $2}'`

if [ "$dist" == "Ubuntu" ]; then
  echo "ubuntu"
else
  echo "not ubuntu"
fi
| improve this answer | |
  • 1
    This can probably be simplified using the lsb_release tool, which should read out the same files. lsb_release -i reports either Distributor ID: Ubuntu or Distributor ID: CentOS in these cases. – chronitis May 2 '14 at 9:31
  • @chronitis: yes, sure it can be – jobin May 2 '14 at 9:32
  • I don't think it's available by default on Centos though – Sylvain Pineau May 2 '14 at 9:33
2

The lsb_release command was added to the Linux Standard Base (ISO/IEC 23360) for this purpose:

$ lsb_release -si
Ubuntu
$ lsb_release -sd
Ubuntu 18.04.3 LTS
$ lsb_release -sr
18.04
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.3 LTS
Release:        18.04
Codename:       bionic

Therefore a case statement along the lines of

case "`/usr/bin/lsb_release -si`" in
  Ubuntu) echo 'This is Ubuntu Linux' ;;
       *) echo 'This is something else' ;; 
esac

should do what you want.

On newer Linux distributions based on systemd there is also /etc/os-release, which is intended to be included into shell scripts with the source (.) command, as in

. /etc/os-release

case "$ID" in
  ubuntu) echo 'This is Ubuntu Linux' ;;
       *) echo 'This is something else' ;; 
esac

But in the use-case example you gave, you may actually be more interested not in the name of the distribution, but whether it has apt-get or yum. You could just test for the presence of the files /usr/bin/apt-get or /usr/bin/yum with if [ -x /usr/bin/apt-get ]; then ... or for the presence of associated infrastructure directories, such as /var/lib/apt and /etc/apt/.

| improve this answer | |
1

Execute /etc/os-release in a sub shell and echo its value:

if [ "$(. /etc/os-release; echo $NAME)" = "Ubuntu" ]; then
  apt-get install updates 
else
  yum update
fi
| improve this answer | |
0

I would use python

if ! python -c "exec(\"import platform\nexit ('centos' not in platform.linux_distribution()[0].lower())\")" ; then
   echo "It is not CentOS distribution, ignoring CentOS setup"
   exit 0
fi
| improve this answer | |
0

Using this command works in CentOS, Ubuntu and Debian: grep "^NAME=" /etc/os-release |cut -d "=" -f 2 | sed -e 's/^"//' -e 's/"$//'

In Debian it yields Debian GNU/Linux, in Ubuntu it yields Ubuntu and in CentOS it yields CentOS Linux.

The benefit of using grep, cut and sed instead of gawk is clear: Debian does not have gawk installed by default, so you cannot rely on it on random Debian box.

| improve this answer | |
0

lsb_release command is only work for Ubuntu platform but not in centos so you can get details from /etc/os-release file

following command will give you the both OS name and version-

cat /etc/os-release | awk -F '=' '/^PRETTY_NAME/{print $2}' | tr -d '"'

# output :-
# for centos -> CentOS Linux 7 (Core)
# for ubuntu -> Ubuntu 18.04.1 LTS (version differ with different releases)

You can also get the os name and version separately. in your case to run update command you can use following script-

os_name=$(cat /etc/os-release | awk -F '=' '/^NAME/{print $2}' | awk '{print $1}' | tr -d '"')

if [ "$os_name" == "Ubuntu" ]
then
        echo "system is ubuntu"
        os_versionid=$(cat /etc/os-release | awk -F '=' '/^VERSION_ID/{print $2}' | awk '{print $1}' | tr -d '"')

        case $os_versionid in
                "14.04" )
                        echo "os version is 14.04"
                        sudo apt-get update
                        ;;

                "16.04" )
                        echo "os version is 16.04"
                        sudo apt-get update
                        ;;

                "18.04" )
                        echo "os version is 18.04"
                        sudo apt update
                        ;;
        esac
elif [ "$os_name" == "CentOS" ]
then
        echo "system is centos"
        sudo yum update
else
        echo "system is $os_name"
fi
| improve this answer | |
0

Awk is supported on almost every nix system so this should be enough so we not have to care about all tools.

#!/bin/bash

DISTRO="$(awk -F= '/^NAME/{print tolower($2)}' /etc/os-release|awk 'gsub(/[" ]/,x) + 1')"

[[ "${DISTRO}" = "gentoo" || "${DISTRO}" = "ubuntu" ]] && \
awk 'BEGIN{print "'${DISTRO}'"}' || \
awk 'BEGIN{print "Unknown distro..."}'

Perl

#!/usr/bin/perl
use Linux::Distribution qw(distribution_name);
if(my $distro = distribution_name) { print "Distro: $distro\n"; } else { print "Unkown distro...n\n";}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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