How to Programmatically Detect Linux Distribution and Version in Bash Scripts


2 views

When writing cross-platform shell scripts, you often need to handle distribution-specific behaviors. Package managers differ between Debian (apt) and RedHat (yum/dnf), configuration files have different locations, and some tools might not be available on all distros.

Here are the most reliable ways to detect your Linux environment:

# Method 1: Using /etc/os-release (most modern systems)
cat /etc/os-release

# Method 2: Checking lsb_release (common but not always available)
lsb_release -a

# Method 3: Parsing uname output
uname -a

Here's a comprehensive function you can include in your scripts:

function get_linux_distro() {
    local DISTRO=""
    local VERSION=""
    
    if [ -f /etc/os-release ]; then
        # Modern systems
        DISTRO=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"')
        VERSION=$(grep -oP '(?<=^VERSION_ID=).+' /etc/os-release | tr -d '"')
    elif [ -f /etc/lsb-release ]; then
        # Older Ubuntu/Debian
        DISTRO=$(grep -oP '(?<=^DISTRIB_ID=).+' /etc/lsb-release | tr -d '"')
        VERSION=$(grep -oP '(?<=^DISTRIB_RELEASE=).+' /etc/lsb-release | tr -d '"')
    elif [ -f /etc/redhat-release ]; then
        # RHEL/CentOS
        DISTRO=$(sed 's/^$.*$ release.*/\1/' /etc/redhat-release)
        VERSION=$(sed 's/^.* release $[0-9.]\+$.*/\1/' /etc/redhat-release)
    else
        # Fallback to uname
        DISTRO=$(uname -s)
        VERSION=$(uname -r)
    fi
    
    echo "${DISTRO,,} ${VERSION}"
}

Here's how you might use this detection in a real script:

#!/bin/bash

# Get distro info
read -r DISTRO VERSION < <(get_linux_distro)

case $DISTRO in
    debian|ubuntu)
        # Debian-based systems
        apt-get update
        apt-get install -y package-name
        ;;
    centos|rhel|fedora)
        # RedHat-based systems
        if command -v dnf >/dev/null; then
            dnf install -y package-name
        else
            yum install -y package-name
        fi
        ;;
    *)
        echo "Unsupported distribution: $DISTRO"
        exit 1
        ;;
esac

Some distributions need special handling:

# Alpine Linux uses apk
if [ -f /etc/alpine-release ]; then
    apk add --no-cache package-name
fi

# Arch Linux uses pacman
if [ -f /etc/arch-release ]; then
    pacman -Sy --noconfirm package-name
fi

You might need to handle different versions differently:

# Example: Different Python versions on Ubuntu
if [[ "$DISTRO" == "ubuntu" ]]; then
    case $VERSION in
        18.04)
            apt-get install -y python3.6
            ;;
        20.04)
            apt-get install -y python3.8
            ;;
        22.04)
            apt-get install -y python3.10
            ;;
    esac
fi

1. Always prefer /etc/os-release when available
2. Provide clear error messages for unsupported distros
3. Test your scripts on multiple distributions
4. Consider using Docker for cross-distro testing


When writing shell scripts or developing cross-platform applications, you often need to handle different Linux distributions differently. Package names, configuration file locations, and even system commands can vary between distributions like Ubuntu, CentOS, or Arch Linux.

Most Linux distributions include identification files in the /etc/ directory. Here are the most common ones:

# Check common release files
ls -l /etc/*-release
ls -l /etc/*_version

Modern Linux systems (systemd-based) use /etc/os-release as the standard location for distribution information:

#!/bin/bash

if [ -f /etc/os-release ]; then
    . /etc/os-release
    echo "Distribution: $NAME"
    echo "Version: $VERSION_ID"
else
    echo "Not a modern Linux distribution"
fi

For older systems that don't have /etc/os-release, you can check distribution-specific files:

get_distro() {
    if [ -f /etc/redhat-release ]; then
        echo "RedHat/CentOS"
    elif [ -f /etc/debian_version ]; then
        echo "Debian/Ubuntu"
    elif [ -f /etc/SuSE-release ]; then
        echo "SUSE"
    elif [ -f /etc/arch-release ]; then
        echo "Arch"
    else
        echo "Unknown"
    fi
}

Some distributions provide specific commands for version checking:

# For Debian/Ubuntu
lsb_release -a

# For RedHat/CentOS
cat /etc/redhat-release

# For Alpine
cat /etc/alpine-release

Remember that the Linux kernel version is different from the distribution version. To check the kernel:

uname -r

Here's how you might use this in a real script to install packages differently based on the distribution:

#!/bin/bash

if [ -f /etc/os-release ]; then
    . /etc/os-release
    case $ID in
        debian|ubuntu)
            apt-get install -y mypackage
            ;;
        centos|rhel)
            yum install -y mypackage
            ;;
        arch)
            pacman -S mypackage
            ;;
        *)
            echo "Unsupported distribution"
            exit 1
            ;;
    esac
fi
  • Always check for /etc/os-release first
  • Fall back to distribution-specific checks if needed
  • Consider using the lsb_release command when available
  • Document your script's distribution requirements
  • Test on multiple distributions

For more complex scenarios, you might want to use Python's platform module:

import platform
print(platform.linux_distribution())