62

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
αғsнιη
  • 35,660
shekhar
  • 807

14 Answers14

90

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.

terdon
  • 100,812
  • "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 03:29
  • Gawk is not installed in Debian by default. – Ville Laitila Apr 20 '18 at 08: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 08:05
  • 1
    Even more specific using lsb_release: lsb_release -d | awk -F"\t" '{print $2}' | awk -F " " '{print $1}' – NerdOfCode Nov 04 '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 05 '18 at 09:21
  • @terdon Oops... Wasn't thinking. – NerdOfCode Nov 11 '18 at 23:03
  • The script in 2 also works well on mingw/msys2 and macos - fyi – Goblinhack Jun 10 '23 at 14:42
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.

11

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  
Harris
  • 2,598
10

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
Adam
  • 109
7

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/.

6
 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.

Jakuje
  • 6,605
  • 7
  • 30
  • 37
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
  • 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 03:22
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
jobin
  • 27,708
1

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
chitresh
  • 111
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
jobwat
  • 231
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
Can Tecim
  • 101
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.

0

Following @terdon's answer, I like the simple solution below:

gcc --version | grep "Red Hat"
if [ "$?" -eq 0 ]; then
    echo "OK, on centos"
fi

gcc --version | grep Ubuntu if [ "$?" -eq 0 ]; then echo "OK, on Ubuntu" fi

-1

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";}
wuseman
  • 99