How to Check Your Ubuntu (or Any Linux) Version from the Command Line

Devops & Infrastructure and Tips & Tricks

How to Check Your Ubuntu (or Any Linux) Version from the Command Line

Knowing exactly which Ubuntu version a server runs sounds like a question with one answer — but Linux gives you at least five commands that report it, and each one tells you something slightly different. This guide covers the ones worth knowing, when each is the right tool, and the cross-distro version that works regardless of what distribution you're actually on.

The fastest answer

If you just want the version and you're on Ubuntu (or any modern Debian-based system):

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 24.04.1 LTS
Release:        24.04
Codename:       noble

That's the canonical answer. Description gives you the marketing name (Ubuntu 24.04.1 LTS), Release gives you the numeric version you'd write in a Dockerfile (24.04), and Codename gives you the adjective-animal name Ubuntu releases get (noble, jammy, focal).

If lsb_release: command not found, install the package — on Ubuntu Server minimal installs it's not preinstalled:

sudo apt-get install -y lsb-release

The cross-distro answer: /etc/os-release

Every distribution that uses systemd ships an /etc/os-release file with standardised fields. It's the right command to reach for in any script that might run across multiple distros (Ubuntu, Debian, AlmaLinux, Rocky, Fedora, Amazon Linux, Alpine):

cat /etc/os-release
PRETTY_NAME="Ubuntu 24.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.1 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"

To extract just one field — useful in shell scripts:

. /etc/os-release            # source it as shell variables
echo "$ID $VERSION_ID"       # ubuntu 24.04
echo "$VERSION_CODENAME"     # noble

ID is the lowercase distribution identifier (ubuntu, debian, almalinux, rocky, rhel, amzn, alpine), and VERSION_ID is the major version. Those two are the right pair to branch on in a portable deploy script — see the Linux distros for deployment guide for context on which IDs your servers might actually report.

hostnamectl — systemd's built-in

hostnamectl was designed for setting the hostname, but it also dumps OS metadata as a side effect:

hostnamectl
 Static hostname: web-prod-01
       Icon name: computer-vm
         Chassis: vm
      Machine ID: 7c3d8a9e2f1b4c6d8e0f1a2b3c4d5e6f
         Boot ID: a1b2c3d4e5f60718293a4b5c6d7e8f90
  Virtualization: kvm
Operating System: Ubuntu 24.04.1 LTS
          Kernel: Linux 6.8.0-31-generic
    Architecture: x86-64

It's the most informative single command — it tells you the distro version and the kernel and whether you're running in a VM. On any systemd system it works without extra packages installed.

uname — kernel, not distro

uname reports the kernel, which is not the same thing as the distribution. Treating it as a distro check is one of the most common mistakes:

uname -a
Linux web-prod-01 6.8.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Thu May 30 21:00:00 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

The output mentions Ubuntu, but that's part of the Ubuntu-specific kernel build identifier. On an Amazon Linux box running a Red Hat-flavoured kernel you'd see .el9.x86_64 instead. uname -r alone gives you the kernel version (6.8.0-31-generic), which matters when you're checking module compatibility, but it doesn't tell you whether the distro is Ubuntu 22.04 or 24.04.

Use uname for kernel-related decisions, not distribution-version decisions.

/etc/issue and /etc/issue.net — the legacy options

Some older guides recommend these:

cat /etc/issue
Ubuntu 24.04.1 LTS \n \l

The \n and \l are escape sequences expanded at login time (hostname and tty line). /etc/issue is what gets shown above the login prompt on a serial console. It's editable as a free-form file, so on hardened or customised systems it might contain a banner instead of the OS version. Don't rely on it in scripts — /etc/os-release is the right substitute.

Cross-distro examples — what you'll see on each

The output of /etc/os-release on the other distros covered earlier:

Debian 12:

PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian

AlmaLinux 9:

NAME="AlmaLinux"
VERSION="9.4 (Seafoam Ocelot)"
ID="almalinux"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.4"
PLATFORM_ID="platform:el9"
PRETTY_NAME="AlmaLinux 9.4 (Seafoam Ocelot)"

Amazon Linux 2023:

NAME="Amazon Linux"
VERSION="2023"
ID="amzn"
ID_LIKE="fedora"
VERSION_ID="2023"
PRETTY_NAME="Amazon Linux 2023.5.20240805"
PLATFORM_ID="platform:al2023"

Alpine 3.20:

NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.20.3
PRETTY_NAME="Alpine Linux v3.20"
HOME_URL="https://alpinelinux.org/"

Notice that AlmaLinux and Amazon Linux both set ID_LIKE to fedora / rhel — that's the field to branch on when you want anything in the RHEL family rather than a specific distro. Debian-derivatives (Ubuntu, Mint) set ID_LIKE=debian.

Scripting version checks in CI

A common pattern in deploy scripts: gate a step on the distro and version. The portable version:

#!/usr/bin/env bash
set -euo pipefail

. /etc/os-release

case "$ID" in
  ubuntu|debian)
    sudo apt-get update
    sudo apt-get install -y nginx
    ;;
  almalinux|rocky|rhel|fedora|amzn)
    sudo dnf install -y nginx
    ;;
  *)
    echo "Unsupported distro: $ID" >&2
    exit 1
    ;;
esac

For an exact-version check (some deploy steps only support specific versions):

. /etc/os-release

if [[ "$ID" == "ubuntu" && "$VERSION_ID" == "24.04" ]]; then
  echo "Detected Ubuntu 24.04 — using the noble apt source"
fi

The [[ ... ]] test treats VERSION_ID as a string, which is what you want — 24.04 is a label, not a number. (Bash float arithmetic would interpret 24.04 and 24.10 as 24.04 and 24.1 respectively, which is exactly the wrong thing.)

For richer version comparisons (greater-than-or-equal), use dpkg --compare-versions on Debian-family or rpm -q --qf on RHEL-family rather than rolling your own.

Container-specific: how cat /etc/os-release behaves inside containers

Inside a Docker container, cat /etc/os-release reports the image's distro, not the host's. A Debian-slim container running on an Amazon Linux host:

docker run --rm debian:12-slim cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
ID=debian

That's usually what you want — the script inside the container should see the container's filesystem. But it does mean what distro is this server? gives different answers depending on whether you're asking the host or a container. The host answer comes from cat /etc/os-release on the bare metal; the container answer comes from inside docker exec.

For Kubernetes nodes, the right place to check the host OS is via the kubelet's nodeInfo field (kubectl get nodes -o wide) or by ssh'ing into the node directly.

Knowing your distro version unlocks the rest of the server-ops command set:

For deploys themselves, DeployHQ is distro-agnostic — the build pipelines feature runs your build inside a container, and the deploy lands on whichever Linux distribution your target servers happen to run. Start a free trial to wire any of these distros into a Git-driven deploy workflow.


Need help? Email support@deployhq.com or follow @deployhq on X.