Here are a few commands you can use to find out which Linux distribution you’re on — pick whichever your system has:
1 2 3 4 5 6 7 | cat /etc/issue cat /proc/version dmesg | head -1 cat /etc/*-release |
Of those, cat /etc/*-release is the most reliable on modern systems. The wildcard catches both /etc/os-release (the systemd-mandated standard, present on virtually all distros since around 2012) and any distro-specific files like /etc/redhat-release, /etc/lsb-release, or /etc/debian_version — so you don’t need to know in advance what the file is called.
If you only want a clean machine-readable answer and don’t care about the others, source /etc/os-release and read its variables directly:
1 2 | . /etc/os-release echo "$NAME $VERSION_ID" # e.g. "Ubuntu 22.04" |
A few useful additions: commands that work the same across distros.
One of the joys of Linux is that once you’ve learned the basics, the same commands work whether you’re on Ubuntu, Fedora, Arch, Alpine, or Amazon Linux. Here are some that show up in almost every troubleshooting session:
What kernel and architecture am I on?
1 2 3 | uname -a # full kernel info: kernel name, hostname, release, arch uname -r # just the kernel release (useful for matching kernel modules) arch # CPU architecture: x86_64, aarch64, armv7l, etc. |
How much memory and disk do I have?
1 2 3 | free -h # memory: human-readable units df -h # disk usage by filesystem du -sh /var/log # size of a specific directory |
What’s running and using resources?
1 2 3 | ps aux # all processes, BSD-style output top # interactive process viewer (q to quit) htop # nicer interactive viewer (often needs install) |
Who am I, where am I, what’s the time?
1 2 3 4 5 6 | whoami # current user id # user + group IDs hostname # machine name pwd # current directory date # current date and time, with timezone uptime # how long the system has been running, plus load average |
Networking basics. The classic ifconfig and netstat are deprecated in favor of ip and ss, which ship with iproute2 and are present on every modern distro:
1 2 3 4 5 | ip addr # network interfaces and their IPs (replaces ifconfig) ip route # routing table (replaces route) ss -tulpn # listening TCP/UDP sockets with PIDs (replaces netstat) ping -c 4 example.com # send 4 ICMP packets and stop curl -I https://example.com # fetch just response headers |
Which desktop am I running? If you ssh into a graphical box and aren’t sure whether it’s GNOME, KDE Plasma, XFCE, Cinnamon, or something else, two environment variables will tell you:
1 2 | echo $XDG_CURRENT_DESKTOP # GNOME, KDE, XFCE, MATE, X-Cinnamon, etc. echo $DESKTOP_SESSION # the session name (often more specific) |
Both are set by the display manager when you log in graphically; they’re empty if you’re on a headless box or in a plain ssh shell that didn’t inherit them. If they come back empty but you know there’s a desktop running, this works too:
1 | ps -e | grep -Eo 'gnome-shell|plasmashell|xfce4-session|cinnamon|mate-session' | head -1 |
X11 or Wayland? Once you’ve got a desktop, the next question is which display server it’s drawing through. The simplest check is the session-type variable, set by systemd’s logind:
1 | echo $XDG_SESSION_TYPE # "x11" or "wayland" |
If that’s empty (again, common over plain ssh), use loginctl to ask the session manager directly:
1 2 | loginctl show-session $(loginctl | awk 'NR==2 {print $1}') -p Type # Type=wayland |
And if you want to see whether the Wayland or X11 socket actually exists on the system:
1 2 | ls /run/user/$(id -u)/wayland-* # Wayland socket(s) for your user ls /tmp/.X11-unix/ # X11 sockets (one per :display) |
Why this matters: some tools behave differently or don’t work at all under Wayland (screenshot utilities, screen sharing, global hotkey daemons, automation tools like xdotool). When something graphical “just doesn’t work” on a modern Linux desktop, “are you on Wayland?” is often the first question to ask.
Looking for files and text.
1 2 3 4 | find / -name "*.conf" 2>/dev/null # find files by name grep -rni "error" /var/log # recursive case-insensitive search locate sshd_config # very fast — uses an index, may need updatedb which python3 # path to a command in $PATH |
Permissions and ownership.
1 2 3 4 | ls -la # detailed listing with permissions stat /etc/passwd # all metadata for a file chmod 644 file.txt # rw for owner, r for group/others chown user:group file.txt # change owner and group |
Service management. Systemd is the init system on virtually every mainstream distro now (Debian, Ubuntu, RHEL/Fedora, SUSE, Arch). The same systemctl commands work everywhere:
1 2 3 4 5 6 | systemctl status nginx # is it running? systemctl start nginx systemctl stop nginx systemctl enable nginx # auto-start at boot systemctl restart nginx journalctl -u nginx -f # tail the service's logs |
Alpine and a few minimalist distros use OpenRC instead (rc-service, rc-update) — worth knowing when you ssh into a small container.
Where the distros do diverge: package management. This is the one place you have to know which family you’re on:
1 2 3 4 5 | Debian / Ubuntu apt install <pkg> apt update / apt upgrade RHEL / Fedora / CentOS dnf install <pkg> dnf update (yum on older releases) openSUSE zypper install <pkg> zypper refresh / zypper update Arch pacman -S <pkg> pacman -Syu Alpine apk add <pkg> apk update / apk upgrade |
If a script needs to work across families, the cleanest pattern is to detect $ID from /etc/os-release and dispatch:
1 2 3 4 5 6 7 8 | . /etc/os-release case "$ID" in ubuntu|debian) apt install -y curl ;; rhel|centos|fedora) dnf install -y curl ;; arch|manjaro) pacman -S --noconfirm curl ;; alpine) apk add curl ;; *) echo "unsupported distro: $ID"; exit 1 ;; esac |
That’s the foundation. Once you have these committed to muscle memory, ssh-ing into an unfamiliar Linux box stops being intimidating — the same handful of commands answer the same handful of questions everywhere.