uname — Print kernel and OS identification — version, arch, hostname across all 5 shells
Equivalents in every shell
uname -aExternal binary from coreutils. `uname` alone prints just the kernel name (`Linux`, `Darwin`, `FreeBSD`, `MINGW64_NT-10.0-19045` for Git Bash on Windows). Flags: `-s` kernel name, `-r` kernel release, `-m` machine arch (`x86_64`, `aarch64`, `arm64`), `-n` hostname, `-p` processor, `-o` OS (Linux: `GNU/Linux`; macOS: errors). `-a` is "all". For script branching, `case "$(uname -s)" in Linux*) ;; Darwin*) ;; esac` is the idiomatic OS check.
uname -aSame external. Zsh-specific: the `$MACHTYPE`, `$OSTYPE`, and `$VENDOR` variables are set by the shell at startup — `$OSTYPE` is `linux-gnu` on Linux, `darwin24` on macOS Sequoia, etc. Faster than forking `uname` for hot loops. Bash sets `$OSTYPE` too but the exact string varies.
uname -aSame external. Fish exposes `$os` (set on startup: `Linux`, `Darwin`, `WindowsNT`, etc) and `$hostname` as built-in variables — `if test $os = Linux ...` skips the fork. For arch: `uname -m` still wins (no built-in equivalent).
[System.Environment]::OSVersionThe .NET `OperatingSystem` API: `Platform` (Win32NT / Unix), `Version` (e.g. `10.0.19045.0`), `ServicePack`, `VersionString`. For a fuller dump: `Get-ComputerInfo` (Windows-only, slow ~3s — gathers EVERYTHING). For pwsh's self-reported runtime: `$PSVersionTable` shows `PSVersion`, `OS` (a free-form string like `Microsoft Windows 10.0.19045` or `Darwin 23.4.0 Darwin Kernel Version ...`), `Platform` (`Win32NT` / `Unix`). For just-arch: `[System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture` (`X64`, `Arm64`).
ver`ver` (built-in) prints one line: `Microsoft Windows [Version 10.0.19045.5371]`. For the architecture: `echo %PROCESSOR_ARCHITECTURE%` (`AMD64`, `ARM64`, `x86`). The richest cmd-side option is `systeminfo` (~5s, ~200 lines covering build, install date, BIOS, NICs). For specific fields: `systeminfo | findstr /B /C:"OS Name" /C:"OS Version" /C:"System Type"`. Or `wmic os get Name,Version,OSArchitecture /value` (deprecated since 2023 but still installed).
Worked examples
Print kernel name (for OS-family branching)
uname -suname -s[System.Environment]::OSVersion.PlatformverPrint CPU architecture
uname -muname -m[System.Runtime.InteropServices.RuntimeInformation]::OSArchitectureecho %PROCESSOR_ARCHITECTURE%Branch on OS in a portable script
case "$(uname -s)" in Linux*) echo linux ;; Darwin*) echo macos ;; *) echo other ;; esacswitch (uname -s); case Linux; echo linux; case Darwin; echo macos; case "*"; echo other; endif ($IsWindows) { "windows" } elseif ($IsLinux) { "linux" } elseif ($IsMacOS) { "macos" }Gotchas
- macOS `uname -s` returns `Darwin`, NOT `macOS` or `OSX`. Scripts that test for `[[ "$(uname -s)" == "macOS" ]]` will never match a real Mac. The right form is `Darwin*` (with glob) or `[[ "$(uname -s)" == "Darwin" ]]` exact. `uname -o` (which would return `Darwin` cleanly on Linux as `GNU/Linux`) is NOT supported on BSD `uname` — calling it on macOS produces a usage error.
- On Git Bash for Windows, `uname -s` returns something like `MINGW64_NT-10.0-19045` — not `Linux`, not `Windows`. Scripts that match `Linux*` skip Git Bash; scripts that match `*Windows*` skip Git Bash. The canonical glob is `MINGW*|MSYS*|CYGWIN*`. For WSL: `uname -s` is `Linux` AND `uname -r` contains the substring `Microsoft` or `WSL2` (the kernel build string identifies the WSL kernel).
- pwsh `$IsWindows`, `$IsLinux`, `$IsMacOS` are automatic variables — set by the engine on startup, fast, reliable. BUT they only exist on pwsh 6+. Windows PowerShell 5.1 (legacy, default on Windows pre-2022) does NOT define them; the workaround is `$IsWindowsPS5 = ($PSVersionTable.PSEdition -eq "Desktop")` (Desktop = Win-only 5.x; Core = pwsh 6+).
- `uname -p` (processor) is unreliable across systems. Linux often returns `unknown`; macOS returns `i386` even on Apple Silicon (Rosetta-emulation reporting quirk); BSD systems return the kernel's view, not the CPU. Use `uname -m` (machine arch) instead — it's consistently set and what you actually want for "is this ARM or x86".
- On WSL2, `uname -r` returns the WSL2 Linux kernel version (`5.15.167.4-microsoft-standard-WSL2`), NOT the Windows host's kernel version. To get the Windows-host version from inside WSL: `cmd.exe /c ver`. The WSL kernel is a Microsoft fork independent of the Linux distro's claimed kernel; `cat /proc/version` shows the full build string with `Microsoft` in it as the WSL signature.