Your audit is next week. Someone asked for a clean list of Linux systems in scope, and the output you got is a mess.
One server shows Linux 5.15.0. Another shows Ubuntu 22.04.3 LTS. A third gives almost nothing useful. That's how teams end up handing bad evidence to an auditor and wasting time during a pentest, pen test, or full penetration testing engagement.
If you need a command to check OS version in Linux, stop treating this like a trivia question. For compliance, scoping, and vulnerability mapping, you need the distribution version, not just the kernel.
Stop Gathering Wrong OS Version Data
Your audit request lands on Friday afternoon. The evidence sheet says “OS version,” and your team exports uname -r from every Linux host. On paper, it looks complete. In an audit, it fails fast.
A kernel string is not the operating system version. If your evidence says 5.15.0, the reviewer still does not know whether that host is Ubuntu 22.04, Debian 12, Rocky Linux 9, or something older that has already fallen out of support. That gap causes rework, weakens scoping, and slows down a SOC 2 pentest.
For compliance evidence, collect the distribution and release first. Then add the kernel version as supporting detail.
Audit rule: If your screenshot or script output only shows the kernel, expect follow-up questions.
What Auditors Need
Auditors and pentesters need evidence they can map to patching responsibility, support lifecycle, and asset ownership. The distro name and release do that. The kernel alone does not.
Use this split:
- Kernel version:
5.15.0 - Distribution version:
Ubuntu 22.04,Debian 12,Rocky Linux 9 - Good audit evidence: distro and release, plus kernel if you want complete technical context
If you need a clean reference to determine Linux operating system, use methods that return the distro name in plain text and are easy to parse in a script.
The fast fix
Run both commands and save the output with the hostname and timestamp:
cat /etc/os-release
uname -r
That gives you evidence an auditor can review and a pentester can use for scoping and reporting. It also avoids one of the most common mistakes in Linux inventories. Mixing up the OS with the kernel and submitting the wrong data.
The Best Commands for Accurate OS Versions
If your goal is to identify the Linux distribution cleanly, start with commands that were built for that job.
The two most useful options are lsb_release -a and cat /etc/os-release. They give you the distribution name and release information that matter for compliance evidence and penetration test scoping.

Use lsb_release when available
Run:
lsb_release -a
Typical output looks like this:
- Distributor ID Ubuntu
- Description Ubuntu 22.04.3 LTS
- Release 22.04
- Codename jammy
That's readable, easy to screenshot, and easy to paste into a pentest scope sheet. If you need a simple reference for how to determine Linux operating system, this method is one of the cleanest.
Use os-release as your default
Run:
cat /etc/os-release
Typical output looks like this:
NAME="Ubuntu"VERSION="22.04.3 LTS (Jammy Jellyfish)"ID=ubuntuVERSION_ID="22.04"
This is the command I trust most for day-to-day evidence gathering. It's simple, built for parsing, and usually present even when extra packages are missing.
cat /etc/os-releaseis usually the safest answer when you need one command that works well for both humans and scripts.
My recommendation
Use these in this order:
- Start with
/etc/os-releasebecause it's script-friendly and usually present - Use
lsb_release -aif you want cleaner human-readable output - Record both distro and version in your evidence file, not just one or the other
If you're preparing for a penetration test, pen testing review, or compliance assessment, don't hand over vague system labels. Give exact distro names and releases. That saves time, cuts back on false assumptions, and helps the tester focus on actual findings instead of basic cleanup.
Why Uname Can Mislead Your Security Audit
uname is useful. It's also one of the most misused commands in Linux security work.
The command itself is old, standard, and reliable for what it was meant to do. The GeeksforGeeks explanation of the uname command notes that uname, short for Unix Name, was established in Unix System V in 1983 and is POSIX-standardized to return kernel and system information, which is why uname -r remains a universal way to get the kernel release.
That's exactly why people overuse it.
What uname actually tells you
Run:
uname -r
You'll get the kernel release.
Run:
uname -a
You'll get a one-line summary with kernel and system details.
That's useful when you're checking for kernel-specific vulnerabilities during a pentest or penetration test. It is not enough to identify the full operating system for compliance records.
Why this matters in real security work
Two different Linux distributions can run similar kernel versions while having very different patch histories, package sources, support status, and default security settings.
If your scoping sheet says only Linux 5.15.0, your tester still has to figure out whether that host is Ubuntu, Debian, Red Hat compatible, or something else. That slows down the engagement and increases the odds of bad assumptions.
Practical takeaway: Use
unamefor kernel checks. Don't use it as your only command to check OS version in Linux.
Here's the clean comparison:
| Command | What It Shows | Best For |
|---|---|---|
uname -r | Kernel release version | Checking kernel-level exploit relevance |
uname -a | Kernel and system summary in one line | Quick host context during triage |
cat /etc/os-release | Distribution name and version data | Audit evidence and asset inventory |
lsb_release -a | Distribution details in readable format | Manual verification and screenshots |
The right way to use uname
Use it as a supporting command, not the main answer.
A solid evidence capture looks like this:
cat /etc/os-release
uname -r
uname -a
That order keeps your audit record useful and your penetration testing scope accurate.
Using hostnamectl On Modern Linux Systems
If the box uses systemd, hostnamectl is a nice shortcut.
Run:
hostnamectl
You'll usually see a summary that includes the hostname, operating system, kernel, and architecture. For a quick on-screen check, it's convenient and easy to read.

When hostnamectl helps
It's good for:
- Fast manual checks on newer Ubuntu, Debian, Fedora, and similar systems
- Quick screenshots for internal documentation
- One-command summaries when you want OS and kernel data together
Typical usage is dead simple. You run the command and read the Operating System line.
When hostnamectl fails you
It's not universal.
On non-systemd systems, stripped-down builds, or older servers, hostnamectl may be missing or incomplete. That makes it fine for a technician at a terminal, but weak as the only command in an audit collection script.
If you want consistency across mixed Linux environments, keep hostnamectl as a convenience command. Don't build your whole compliance process around it.
Automating OS Checks for Penetration Testing
Your auditor asks for proof of OS versions across Linux assets. Your team sends screenshots from different commands, half the hostnames do not match the inventory, and one server reports a kernel version instead of the actual distribution release. That is how evidence gets challenged in a SOC 2 review.
Fix it with one collection method and one output format.

Use a fallback chain
For audit evidence, collect the distribution and kernel separately, then store them in structured output your team can reuse in scoping docs and final reports.
Use this order:
- Read
/etc/os-release - Fall back to
lsb_release - Use
hostnamectlonly if the first two are unavailable - Record
uname -rseparately for the kernel
This avoids the usual reporting mess. Different Linux builds expose version data in different places. If your script assumes one command works everywhere, you get gaps, inconsistent naming, or output that is hard to parse in an audit workbook.
A practical Bash function
Use this:
get_linux_version() {distro=""version=""kernel="$(uname -r 2>/dev/null)"if [ -f /etc/os-release ]; then. /etc/os-releasedistro="${NAME:-$ID}"version="${VERSION_ID:-$VERSION}"elif command -v lsb_release >/dev/null 2>&1; thendistro="$(lsb_release -si 2>/dev/null)"version="$(lsb_release -sr 2>/dev/null)"elif command -v hostnamectl >/dev/null 2>&1; thendistro="$(hostnamectl 2>/dev/null | awk -F: '/Operating System/ {gsub(/^[ \t]+/, "", $2); print $2}')"version=""elsedistro="unknown"version="unknown"fiprintf '{"distro":"%s","version":"%s","kernel":"%s"}\n' "$distro" "$version" "$kernel"}Run:
get_linux_version
That gives you JSON-style output you can drop into an asset inventory, evidence file, or pentest scoping sheet.
My recommendation is simple. Save the output to a file per host, include the hostname and timestamp, and keep the raw command output with your final evidence set. Auditors reject weak evidence because teams cannot show how the data was collected or when it was captured.
How to use this in a real pentest workflow
Run the function over SSH across in-scope hosts, collect the results centrally, and attach them to the kickoff package before testing starts. That saves your pentester from spending billable time cleaning up asset details and chasing version mismatches.
If you want to speed up collection, Affordable Pentesting offers automated tools alongside manual testing workflows. That is useful when you need repeatable evidence for compliance-driven engagements.
Bad prep costs money. Blaze Information Security's pricing guide says standard penetration tests often run from $10,000 to $35,000, and web application tests commonly range from $5,000 to $30,000, according to Blaze Information Security's pentest pricing guide. For smaller engagements, Budget Security reports pentest pricing in the $8,000 to $12,000 range for small-to-medium businesses targeting one or two assets. In the UK and EU market, Secforce's pen testing price guide says a typical day rate is about £1200, with a 3-day web app test around $3,600 and a 15-day engagement around $22,500.
The point is not the exact number. The point is that every hour spent fixing bad scope data is an hour you already paid for.
Get Your Linux Security Right
Checking Linux versions sounds basic. It isn't basic when your pentester needs accurate scope, your compliance officer needs evidence, and your team is already overloaded.
Use the right command for the right job. Use /etc/os-release or lsb_release -a for the distribution. Use uname -r for the kernel. Use hostnamectl when it's available, but don't depend on it everywhere.
What to do next
Keep it simple:
cat /etc/os-release
lsb_release -a
uname -r
hostnamectl
If you're buying a penetration test, ask for certified testers and a clear timeline. OSCP, CEH, and CREST-qualified professionals should be able to work from clean scope data and deliver actionable findings fast. If you need affordable network penetration testing, make sure the provider is talking plainly about evidence quality, reporting speed, and what you'll get.
A cheap report with no real findings is a waste. An expensive report that takes forever is also a waste. The sweet spot is affordable manual pentesting, clear communication, and reports you can use within a week.
If you need a fast, affordable pentest for SOC 2, PCI DSS, HIPAA, ISO 27001, or an internal security review, contact Affordable Pentesting through the contact form for a same-day quote.
