Do you have multiple vms and real machines you use for random testing, and small tasks? need to know what machine you are on? what kernel you are using? what the current Linux distribution info is? what OS version did you last install on here? and more such questions? well! we have some of the answers for you. well maybe not answers, but more like small tools so you can get the answers!
Distribution info
lsb_release -a on my ubuntu system it gives the following result : $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu Xenial Xerus (development branch) Release: 16.04 Codename: xenial On a debian system it gives the following result :
lsb_release -a
No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 8.4 (jessie) Release: 8.4 Codename: jessie If lsb_release -a doesn’t cut it for you then you can try cat /etc/issue
as a result we see the following examples :
cat /etc/issue
Debian GNU/Linux 8 \n \l
$ cat /etc/issue Ubuntu Xenial Xerus (development branch) \n \l In some cases where you suspect you are on centos or redhat, maybe because you noticed the package versions are old enough to be used by columbus while sailing the open seas, then you can use either
cat /etc/centos-release
or
cat /etc/redhat-release
which will give you result such as : CentOS release 6.2 (Final)
Kernel Info
now as far as finding the kernel info goes you can get all the info you need via uname. $ uname -a Linux testhost 4.4.0-9-generic #24-Ubuntu SMP Mon Feb 29 19:33:19 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux $ uname -r 4.4.0-9-generic as you can see uname -r gives you just the kernel version and uname -a gives you multiple pieces of info, like date the kernel was compiled, the arch (i.e. x86_64).
The Modern Way: /etc/os-release
Here’s the thing — lsb_release is increasingly AWOL on minimal installs, containers, and anything that wasn’t set up by someone who cared. Alpine doesn’t ship it. Distroless images definitely don’t. Even some Debian minimal installs skip it to save space.
The file you actually want is /etc/os-release. It’s been the standard since systemd became ubiquitous, and unlike lsb_release, it’s almost always there:
$ cat /etc/os-releasePRETTY_NAME="Ubuntu 24.04.1 LTS"NAME="Ubuntu"VERSION_ID="24.04"VERSION="24.04.1 LTS (Noble Numbat)"ID=ubuntuID_LIKE=debianHOME_URL="https://www.ubuntu.com/"SUPPORT_URL="https://help.ubuntu.com/"BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"The ID and VERSION_ID fields are what you want if you’re parsing this in a script — they’re consistent and machine-readable, unlike the human-friendly PRETTY_NAME which changes formatting between distros constantly.
hostnamectl — The One Ring
If you’re on a systemd-based system (which is most things that aren’t Alpine or containers), hostnamectl dumps everything in one shot:
$ hostnamectl Static hostname: myserver Icon name: computer-vm Chassis: vm 🖥️ Machine ID: a3f2c1d4e5b6a7c8d9e0f1a2b3c4d5e6 Boot ID: 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d Virtualization: kvmOperating System: Debian GNU/Linux 12 (bookworm) Kernel: Linux 6.1.0-21-amd64 Architecture: x86-64That Virtualization: kvm line is gold. No more guessing whether you’re on a VM or bare metal — it tells you KVM, VMware, Hyper-V, or nothing at all for physical hardware.
Gotchas Worth Knowing
lsb_release returning nothing useful in a container: You’re probably in a minimal Docker image. Drop back to /etc/os-release or just cat /etc/debian_version for Debian-based images. It won’t have everything, but it’ll tell you the series.
uname -r lying to you in WSL: Inside WSL2, uname -r returns the Windows kernel version string, not a “real” Linux kernel version. It looks like 5.15.90.1-microsoft-standard-WSL2. If you’re scripting kernel version checks and someone runs them in WSL, this will bite you — specifically the -microsoft-standard suffix blows up any regex that expects a clean x.y.z-flavor pattern.
Running in a container and hostnamectl fails: hostnamectl talks to systemd-hostnamed via D-Bus. Most containers don’t run systemd, so this command just hangs or throws an error. Fall back to /etc/os-release + uname -r and move on.
The “What Machine Am I On” One-Liner
If you bounce between a lot of boxes and always forget what’s what, drop this alias in your .bashrc or .zshrc:
alias sysinfo='echo "Distro: $(. /etc/os-release && echo $PRETTY_NAME)"; echo "Kernel: $(uname -r)"; echo "Arch: $(uname -m)"; echo "Host: $(hostname)"'Run sysinfo and you get four lines of “where the hell am I” context without having to remember four different commands at 2 AM. Your future self, staring at a terminal with six identical-looking SSH sessions open, will appreciate it.
Scripting It: Detect Distro Family Without Breaking on Edge Cases
At some point you’ll write a script that needs to behave differently on Debian vs RHEL vs Alpine. The naive approach is checking the output of lsb_release -is and regex-matching the string — which fails the second you run it on a minimal container, a RHEL derivative like Rocky Linux, or literally any Alpine system.
The reliable pattern sources /etc/os-release directly using the shell’s built-in . (dot) sourcing, then checks ID_LIKE before falling back to ID:
#!/usr/bin/env bash. /etc/os-release
# ID_LIKE covers derivatives (e.g. Rocky Linux has ID_LIKE="rhel centos fedora")DISTRO_FAMILY="${ID_LIKE:-$ID}"
case "$DISTRO_FAMILY" in *debian* | *ubuntu*) echo "Debian family — using apt" ;; *rhel* | *centos* | *fedora*) echo "RHEL family — using dnf/yum" ;; *alpine*) echo "Alpine — using apk" ;; *) echo "Unknown family: $ID — you're on your own" ;;esacThe ${ID_LIKE:-$ID} trick is the important bit. If ID_LIKE exists (Rocky Linux, AlmaLinux, Linux Mint, etc.), use that — it’s the parent family. If not, fall back to ID directly. This handles the full tree of derivatives without maintaining a whitelist of distro names that grows stale the moment a new fork shows up.
One more gotcha: ID_LIKE can contain multiple space-separated values ("rhel centos fedora"), so use *pattern* glob matching instead of exact equality in your case statement. Exact match will miss it every time.