dmesg — Print the kernel ring buffer — boot probes and runtime events across all 5 shells
Equivalents in every shell
dmesg -T | tail -50`-T` translates the kernel's internal monotonic timestamps to human-readable wall-clock dates (otherwise you get "[12345.678]" seconds-since-boot). `-w` follows new entries (kernel ring buffer additions in real time). `-l err,warn` filters by level. `-k` kernel-only (most dmesg lines already are). On modern kernels, `dmesg` requires CAP_SYSLOG — `sudo dmesg` is the right invocation if you get "Operation not permitted" errors. Alternative: `journalctl -k` reads the same kernel messages via journald.
dmesg -T | tail -50Same Linux binary. macOS has `dmesg` but it works differently — it reads the kernel's circular buffer (limited size, gets overwritten quickly under load). Recent macOS versions restrict `dmesg` to root: `sudo dmesg`. For the FULL macOS equivalent (system + kernel + hardware events) use `log show --last 1h --predicate 'eventMessage CONTAINS "kernel"'` or `system_log` / Console.app for the GUI.
dmesg -T | tail -50Same external. Fish quick-win for "what hardware did the kernel see at last boot": `dmesg | string match -r "(probe|attached|enabled|added)"`. Or filter to just USB hot-plug events: `dmesg -w | string match -r "usb"` (run in a separate window, plug a device in, watch the kernel narrate).
Get-WinEvent -LogName System -ProviderName "Microsoft-Windows-Kernel-General" -MaxEvents 50Windows doesn't have a kernel ring buffer in the Linux sense — kernel events go to the same Event Log structure as everything else, tagged by provider. `Microsoft-Windows-Kernel-General` covers boot / shutdown / power events; `Microsoft-Windows-Kernel-Boot` covers boot; `Microsoft-Windows-Kernel-PnP` covers device add/remove. For ALL kernel-* providers in one query: `Get-WinEvent -ListProvider Microsoft-Windows-Kernel-* | Get-WinEvent`. Hardware-specific drivers (storage, USB) have their own provider names.
wevtutil qe System /q:"*[System[Provider[@Name='Microsoft-Windows-Kernel-General']]]" /f:textcmd-only Windows access is via `wevtutil`. The XPath query `*[System[Provider[@Name='Microsoft-Windows-Kernel-General']]]` matches all events from the kernel general provider. For boot-time hardware probe equivalent, query the `System` log for `Provider="Service Control Manager"` events at boot: `wevtutil qe System /q:"*[System[Provider[@Name='Service Control Manager'] and TimeCreated[timediff(@SystemTime) <= 3600000]]]"`. The pwsh approach is cleaner.
Worked examples
Show last 50 kernel messages
sudo dmesg -T | tail -50sudo dmesg -T | tail -50sudo dmesg -T | tail -50Get-WinEvent -LogName System -ProviderName "Microsoft-Windows-Kernel-General" -MaxEvents 50wevtutil qe System /c:50 /q:"*[System[Provider[@Name='Microsoft-Windows-Kernel-General']]]" /f:text /rd:trueFollow kernel ring buffer (USB plug events)
sudo dmesg -wsudo dmesg -wGet-WinEvent -LogName System -ProviderName "Microsoft-Windows-Kernel-PnP" -MaxEvents 10wevtutil qe System /q:"*[System[Provider[@Name='Microsoft-Windows-Kernel-PnP']]]" /f:text /rd:trueShow only errors and warnings
sudo dmesg -l err,warnsudo dmesg -l err,warnGet-WinEvent -FilterHashtable @{LogName="System"; Level=2,3}wevtutil qe System /q:"*[System[(Level=2 or Level=3)]]"Gotchas
- Modern Linux kernels (5.0+) restrict `dmesg` to root by default via `kernel.dmesg_restrict=1` sysctl. Without sudo you get "Operation not permitted" — surprises users who remember `dmesg` working without sudo on older systems. Either run with sudo, give the user CAP_SYSLOG (`setcap cap_syslog+ep /bin/dmesg`), or use `journalctl -k` which inherits journald's less-strict permissions.
- The kernel ring buffer is BOUNDED in size (typically 1MB, configurable via `CONFIG_LOG_BUF_SHIFT`). On a system with a chatty driver (older Wi-Fi modules, certain SSDs) the buffer can wrap, OVERWRITING earlier boot messages. Diagnostic implication: `dmesg | head` may not actually show boot messages on a long-running system — it shows whatever's still in the ring. `journalctl -b -k` (kernel messages from boot, stored persistently) is more reliable for "what did the kernel say at boot".
- In containers (Docker, podman), `dmesg` inside the container reads the HOST's kernel ring buffer — kernels are shared. If you see kernel messages in your container that don't relate to your workload, they're from the host (or another container). This is also a small information-leak surface — some hardening guides recommend running containers with `--cap-drop SYSLOG`.
- On macOS, the `dmesg` binary exists for compatibility but reads a much smaller, less-detailed buffer than Linux. Most kernel events that would appear in Linux's dmesg appear in macOS's unified log via `log show`. If you're porting Linux scripts that parse `dmesg`, expect them to break on macOS — the format and content differ.
- WSL2 `dmesg` works (the WSL VM has its own Linux kernel) but reflects the WSL VM's kernel, NOT the Windows host. Hardware probes the WSL kernel sees are for the WSL VM's virtual hardware (virtual NICs, virtio devices), not for the physical hardware Windows sees. To debug "did Windows see my USB stick?", `Get-PnpDevice` from pwsh is the right tool — `dmesg` from WSL is the wrong one.