Bash Scripting
Operating System
Script Detection
Programming
Linux

How to detect the OS from a Bash script?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Detecting the operating system in a Bash script usually starts with uname, but the right level of detail depends on what you actually need. Sometimes you only need to distinguish Linux from macOS, and sometimes you need distribution-specific information such as Ubuntu versus Fedora.

The Most Portable First Check: uname

For broad operating-system detection, uname -s is the usual starting point.

bash
1#!/usr/bin/env bash
2
3os_name=$(uname -s)
4echo "$os_name"

Typical outputs include:

  • 'Linux'
  • 'Darwin for macOS'
  • 'FreeBSD'

That is often enough when the script only needs coarse branching.

A Simple case Statement

A case statement keeps the logic readable.

bash
1#!/usr/bin/env bash
2
3case "$(uname -s)" in
4  Linux)
5    echo "Running on Linux"
6    ;;
7  Darwin)
8    echo "Running on macOS"
9    ;;
10  *)
11    echo "Unknown or unsupported OS"
12    ;;
13esac

This is a good default if the script needs only major OS families.

Linux Distribution Detection

If you need more detail on Linux, /etc/os-release is usually the best source.

bash
1#!/usr/bin/env bash
2
3if [[ -f /etc/os-release ]]; then
4  . /etc/os-release
5  echo "ID=$ID"
6  echo "NAME=$NAME"
7  echo "VERSION_ID=$VERSION_ID"
8fi

This is much better than guessing distribution based only on uname, because uname -s will usually just say Linux regardless of distro.

Combining OS and Distribution Logic

A practical script often does both:

bash
1#!/usr/bin/env bash
2
3kernel=$(uname -s)
4
5if [[ "$kernel" == "Linux" && -f /etc/os-release ]]; then
6  . /etc/os-release
7  echo "Linux distro: $ID"
8elif [[ "$kernel" == "Darwin" ]]; then
9  echo "macOS"
10else
11  echo "Other OS: $kernel"
12fi

This gives you a clean branch for Linux family and then refines the result with distro metadata.

What About WSL or Similar Environments?

Sometimes the real question is not only "Linux or macOS?" but whether the script is running under a compatibility layer such as WSL.

A simple heuristic is:

bash
if grep -qi microsoft /proc/version 2>/dev/null; then
  echo "Likely WSL"
fi

That is environment-specific, so it should be treated as a secondary check after your normal OS detection.

Keep the Goal in Mind

Do not collect more OS detail than you need. For many scripts, all that matters is one capability difference, such as whether sed -i behaves like GNU sed or BSD sed.

In those cases, sometimes feature detection is better than OS detection. For example, it can be better to test whether a command-line option exists than to infer support indirectly from the platform name.

A Practical Example

Here is a compact script that handles common Linux and macOS branching.

bash
1#!/usr/bin/env bash
2
3case "$(uname -s)" in
4  Linux)
5    if [[ -f /etc/os-release ]]; then
6      . /etc/os-release
7      echo "Linux ($ID)"
8    else
9      echo "Linux"
10    fi
11    ;;
12  Darwin)
13    echo "macOS"
14    ;;
15  FreeBSD)
16    echo "FreeBSD"
17    ;;
18  *)
19    echo "Unsupported OS: $(uname -s)"
20    exit 1
21    ;;
22esac

That is enough for many installation scripts and local tooling wrappers.

Common Pitfalls

The biggest mistake is assuming uname -s tells you the Linux distribution. It does not; it usually only says Linux.

Another issue is parsing random release files with distro-specific assumptions when /etc/os-release would have been the cleaner source.

Developers also sometimes overuse OS detection when feature detection would be more robust. If the real requirement is command behavior, test the command capability directly when possible.

Finally, avoid unquoted variable expansions in shell conditionals. OS-detection code should be boring and reliable.

Summary

  • Use uname -s for broad operating-system detection.
  • Use /etc/os-release when you need Linux distribution details.
  • Combine the two checks when necessary.
  • Prefer feature detection over OS detection when the script only cares about behavior.
  • Keep the branching logic small and explicit so the script remains portable.

Course illustration
Course illustration

All Rights Reserved.