Guide · Linux · about 8 minutes

Linux cheatsheet: commands by task

Every command from the Linux track on one page, grouped by the job you're doing: finding your way around, reading logs, pipes, permissions, processes, services, packages, networking, disks, SSH, loops, scripts and schedules. Plus what the common errors mean, and the Mac differences that trip people up. Each row links to the lesson that explains it.

Last checked October 2026

How to use this page

Find the job you're trying to do, and copy the pattern. Words in capitals, like FILE, NAME or HOST, are yours to replace. Every row links to the lesson that explains it, with real output. Use the print button at the top to keep a copy next to you.

Three habits that make everything here easier:

  • Check where you are before you run anything. Your prompt says which machine you're on: your own computer, a container (root@...) or a server (vagrant@bookshop, sam@bookshop). Most mistakes in this track were the right command on the wrong machine.
  • Read the last line first. Error messages end with the part that matters.
  • Test, then apply. nginx -t, sshd -t and visudo -c check a settings change before it can break anything; reload applies it without dropping anyone.

When Linux says no

Start here when something fails. Match the message, then look where it says.

The message saysIt meansLook atLesson
No such file or directoryThe path doesn't exist from where you are, or has a typopwd, then ls the folder above it2, 3
command not foundNo folder on your PATH has that program. Often it's simply not installedwhich NAME, then apt search1, 8
Permission deniedYour user isn't allowed to do that to that filels -l FILE and id: owner, group, the three permission sets5
status=203/EXECsystemd couldn't run the program in ExecStartThe path, and the x permission on the program7
status=217/USERThe User= in the unit file doesn't existid NAME7
Unable to locate packageapt doesn't know that name, often because the list is stalesudo apt update, then apt search8
Address already in useSomething else is already listening on that portsudo ss -tlnp | grep :PORT8
502 Bad Gatewaynginx is fine, but the program behind it didn't answernginx's error.log, and ss -tln for where the app really listens9, 14
Connection refusedThe machine answered, but nothing is listening on that portsudo ss -tlnp, and the app's port setting9
Timed out, or curl exit code 28Nothing came back at all: often a firewall dropping trafficTest another port on the same machine, then sudo ufw status9, 14
No space left on deviceThe disk is fulldf -h, then sudo du -sh /path/* | sort -h10, 14
df says full after you deleted the fileA program still has the deleted file opensudo lsof +L1, then restart that program10
WARNING: UNPROTECTED PRIVATE KEY FILE!Your private key is readable by others, so SSH won't use itchmod 600 ~/.ssh/KEY11
Permission denied (publickey)The server didn't accept your key, and won't take a passwordOn the server: sudo journalctl -u ssh, usually ownership or modes11
REMOTE HOST IDENTIFICATION HAS CHANGED!The server's key isn't the one your computer remembersA rebuilt server: ssh-keygen -R HOST. Otherwise, stop and find out why11, 15
sudo: a password is requiredsudo -n wouldn't ask, and a password is neededRun sudo -v on its own first11
unbound variableset -u caught a variable that was never setThe variable's name, and where it should be set13
value too great for baseA number with a leading zero, like 09, was read as octaldate +%-S, or $((10#$n))13

What am I standing on?

ToRunLesson
Which kerneluname -s1
The kernel's versionuname -r1
Which distribution, and its versioncat /etc/os-release1
Which macOS version (Mac only)sw_vers1
Which user you arewhoami1
The machine's namehostname1
What process 1 iscat /proc/1/cmdline; echo1
Run one command in a throwaway Linux containerdocker run --rm ubuntu:24.04 <command>1
Get a shell in onedocker run -it --rm ubuntu:24.04 bash1

Moving around and handling files

ToRunLesson
See where you arepwd2
List a folder, including hidden filesls -a2
List with details, sizes readablels -lh2
Details of a folder itselfls -ld /tmp2
Go somewherecd /var/log2
Go up one foldercd ..2
Go homecd ~2
Go back to where you werecd -2
Make folders, including missing parentsmkdir -p a/b/c2
Make an empty filetouch file.txt2
Copy a filecp from.txt to.txt2
Move or renamemv old.txt new.txt2
Delete a file (no undo)rm file.txt2
Delete an empty folderrmdir folder2
Delete a folder and everything in it (no undo)rm -r folder2
Find where a command liveswhich ls2

Reading and searching

ToRunLesson
List several folders at oncels -l logs config3
List everything, all the way downls -R config3
Newest changes lastls -ltr3
Print a whole filecat notes/todo.txt3
First or last lineshead -20 file, tail -20 file3
Count lineswc -l file3
Read page by pageless file3
Follow a log as it's writtentail -f file3
Find lines that matchgrep pattern file3
Ignore case, count, line numbersgrep -i, grep -c, grep -n3
Lines that don't matchgrep -v pattern file3
Context around matchesgrep -B2 -A2 pattern file3
Whole words onlygrep -w 8080 file3
Search a whole folder; just the file namesgrep -r pattern dir, grep -rl pattern dir3
Which distribution, from its settings filegrep PRETTY_NAME /etc/os-release3
Find files by namefind . -name "*.conf"3
Folders only, or files onlyfind . -type d, find . -type f3
Bigger than a sizefind . -size +100M3
Changed more than 30 days agofind . -mtime +303
Leave a folder outfind . -not -path './.git*'3
Run a command on each file foundfind . -size +1M -exec ls -lh {} ;3
See the last command's exit codeecho $?3

Pipes, columns and counts

ToRunLesson
Send one command's output into anothercommand1 | command24
Print one column (any spaces)awk '{print $1}' file4
Print the last columnawk '{print $NF}' file4
Only lines that meet a conditionawk '$9 >= 500' file4
A condition, then one columnawk '$9 == 404 {print $7}' file4
Add up a columnawk '{sum += $10} END {print sum}' file4
A different separatorawk -F' = ' '{print $2}' file4
One piece, with an exact separatorcut -d: -f2 file4
Certain characters of each linecut -c12-13 file4
How many of each, biggest firstsort | uniq -c | sort -rn4
Sort by number, or remove duplicatessort -n, sort -u4
Print certain linessed -n '10,20p' file4
First and last linesed -n '1p;$p' file4
Delete lines that matchsed '/^#/d' file4
Replace text (shows the result only)sed 's/old/new/g' file4
Replace text in the file, keeping a backupsed -i.bak 's/old/new/' file4
Save output, replacing the filecommand > file4
Add output to the end of a filecommand >> file4
Save errorscommand 2> errors.txt4
Save output and errors togethercommand > file 2>&14
Throw errors awaycommand 2>/dev/null4
Save and keep goingcommand | tee file | command24
Sort a file into itself, safelysort -o file file4

Users and permissions

ToRunLesson
Who am I, and my groupswhoami, id5
Someone else's ID and groupsid sam5
List users or groupscat /etc/passwd, cat /etc/group5
A folder's own permissionsls -ld folder5
Permissions as a numberstat -c '%a %A %U %G %n' file5
Add a user who can log inuseradd --create-home --shell /bin/bash sam5
Add a user for an appuseradd --system --shell /usr/sbin/nologin bookshop5
Add someone to a group (keep -a)usermod -aG bookshop sam5
Run one command as another usersu -s /bin/bash bookshop -c 'command'5
Log in as another usersu - sam5
Change owner and groupchown bookshop:bookshop file5
The same, for a folder and everything in itchown -R bookshop:bookshop folder5
Set permissions exactlychmod 640 file, chmod 750 folder5
Change just one thingchmod +x script, chmod o-r file, chmod g+w file5
Settings an app may read but not changeroot:bookshop and 6405
Private: only the ownerchmod 600 file5
Neverchmod 7775

Processes and signals

ToRunLesson
Every processps -ef, or ps aux for memory columns6
One user's processesps -u bookshop6
Choose the columnsps -o pid,ppid,user,stat,etime,cmd -u bookshop6
Biggest users of memory, or processorps aux --sort=-%mem | head, --sort=-%cpu6
The family treeps -ef --forest6
Find by namepgrep -a name, exactly: pgrep -x name6
Count matchespgrep -c name6
Live view (q quits, M memory, P processor)top6
One snapshot of toptop -b -n 1 | head -156
A process's detailscat /proc/PID/status6
Run in the backgroundcommand &6
List, front, backjobs, fg %1, bg %16
Pause what's in frontCtrl+Z6
Ask a process to stopkill PID6
Force it, as a last resortkill -9 PID6
Stop by exact name, for one userpkill -x -u bookshop books-api6
Pause and carry onkill -STOP PID, kill -CONT PID6
Keep going after logoutnohup command > job.log 2>&1 &6
Exit code after a signal128 + its number: 143 TERM, 137 KILL, 130 INT6

Services and the journal

ToRunLesson
Start, stop, restartsudo systemctl start NAME, stop, restart7
Start at every boot, and nowsudo systemctl enable --now NAME7
Don't start at bootsudo systemctl disable NAME7
Everything about itsystemctl status NAME7
Yes-or-no checkssystemctl is-active NAME, is-enabled7
Its main process numbersystemctl show -p MainPID --value NAME7
After editing a unit filesudo systemctl daemon-reload7
Show a unit file, with overridessystemctl cat NAME7
Override a packaged unit safelysudo systemctl edit NAME7
What's running, what's failedsystemctl list-units --type=service --state=running, systemctl --failed7
A service's logsjournalctl -u NAME -n 507
Follow them livejournalctl -u NAME -f7
Since a time, or this bootjournalctl -u NAME --since "1 hour ago", -b7
Anything that went wrong this bootjournalctl -p warning -b7
Write a file as rootecho "text" | sudo tee FILE7
Start, log in to, restart the servervagrant up, vagrant ssh, vagrant reload, on your own computer7

Installing software

ToRunLesson
Refresh the package list (do this first)sudo apt update8
Find a packageapt search NAME, exactly: apt search --names-only '^NAME$'8
Describe itapt show NAME8
Installed and available versionsapt-cache policy NAME8
Installsudo apt install -y NAME8
Remove, keeping settingssudo apt remove NAME8
Remove with its settingssudo apt purge NAME8
Clear packages nothing needssudo apt autoremove8
What can be updatedapt list --upgradable8
Update everythingsudo apt upgrade8
Which package owns a filedpkg -S /usr/sbin/nginx8
Every file in a packagedpkg -L NAME8
Installed, or only settings left (rc)dpkg -l NAME8
Check nginx's settingssudo nginx -t8
Apply them without dropping connectionssudo systemctl reload nginx8
Switch an nginx site onsudo ln -s /etc/nginx/sites-available/NAME /etc/nginx/sites-enabled/NAME8
nginx's logs/var/log/nginx/access.log, error.log8
Run a PostgreSQL commandsudo -u postgres psql -c 'SELECT version();'8
Make a database, list themsudo -u postgres createdb NAME, sudo -u postgres psql -l8

Networking

ToRunLesson
The server's addressesip -br addr, or just hostname -I9
Where traffic goes, and the gatewayip route9
What's listening, on which port and addresssudo ss -tlnp9
Who's on one portsudo ss -tlnp | grep :80809
Connections open right nowsudo ss -tnp9
Turn a name into an addressgetent hosts NAME9
Name a machine yourselfecho "ADDRESS NAME" | sudo tee -a /etc/hosts9
Is the machine reachable?ping -c 2 HOST9
Is the port open?nc -zv HOST PORT9
Does the web service answer?curl -si http://HOST/PATH, every step: curl -v9
Don't wait forevercurl --max-time 5, then echo $?: 7 refused, 28 timed out, 6 no name9
Firewall: allow SSH first, then switch onsudo ufw allow OpenSSH, then sudo ufw enable9
Allow a portsudo ufw allow 80/tcp9
See the rules, numberedsudo ufw status numbered9
Remove a rulesudo ufw delete allow 80/tcp, or sudo ufw delete NUMBER9

Disks and memory

ToRunLesson
How full is every filesystemdf -h10
Out of inodes?df -i10
Disks, partitions and mountslsblk10
Biggest folders, biggest lastsudo du -sh /var/* | sort -h | tail10
Big files, on one filesystemsudo find / -xdev -type f -size +100M -exec ls -lh {} ;10
How much the journal usesjournalctl --disk-usage10
Make a filesystem (erases the disk)sudo mkfs.ext4 /dev/sdb10
Mount, and unmountsudo mount /dev/sdb /srv/data, sudo umount /srv/data10
Where something is mountedfindmnt /srv/data10
A disk's unchanging ID, for fstabsudo blkid10
Check fstab before a reboot doessudo findmnt --verify, then sudo systemctl daemon-reload10
Mount everything in fstabsudo mount -a10
Empty a log that's in usesudo truncate -s 0 FILE10
Deleted files still taking spacesudo lsof +L110
Memory: read the available columnfree -h10
Biggest users of memoryps aux --sort=-%mem | head10
Is there swap?swapon --show10
Was anything killed for memory?sudo journalctl -k | grep -i oom10
Clear downloaded packagessudo apt clean10

SSH, keys and sudo

ToRunLesson
Make a key pair, with a passphrasessh-keygen -t ed25519 -f ~/.ssh/NAME -C "comment"11
A key's fingerprintssh-keygen -lf ~/.ssh/NAME.pub11
A server's host key fingerprint (on the server)sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub11
Log in with a keyssh -i ~/.ssh/NAME user@HOST11
Run one command, and come backssh HOST 'command'11
A command that needs a terminal, like sudossh -t HOST 'sudo command'11
Never prompt, just failssh -o BatchMode=yes HOST11
Copy a file to a serverscp FILE HOST:11
A short name for a serverA Host block in ~/.ssh/config11
Permissions SSH expectsPrivate key 600, ~/.ssh 700, authorized_keys 600, home folder not writable by others11
Why a login failed (on the server)sudo journalctl -u ssh -n 5011
What a user may do with sudosudo -l -U NAME11
Check sudo's rulessudo visudo -c, a new file first: sudo visudo -cf FILE11
Keys only, no rootPasswordAuthentication no, PermitRootLogin no in /etc/ssh/sshd_config.d/10-NAME.conf11
Check, apply, and confirm SSH's settingssudo sshd -t, sudo systemctl reload ssh, sudo sshd -T11
Type your sudo password now, so later commands don't stop to asksudo -v, on its own line, before pasting several commands11
Make sudo forget your password straight awaysudo -k11

Loops, tests and one-liners

ToRunLesson
See the last exit statusecho $?12
Run B only if A worked, or failedA && B, A || B12
Ask a yes-or-no questiongrep -q TEXT FILE, systemctl is-active --quiet NAME12
Test a file, folder or number[ -f PATH ], [ -d PATH ], [ "$n" -ge 10 ]12
Choose between two pathsif TEST; then ...; else ...; fi12
Once for each filefor f in *.csv; do CMD "$f"; done12
Once for each numberfor i in {1..5}; do ...; done12
Once for each line of a filewhile IFS=: read -r a b rest; do ...; done < FILE12
Wait until something worksuntil CMD; do sleep 1; done12
Leave a loop earlybreak12
Cut an ending off a name"${f%.csv}"12
Many files, anywhere in a folderfind DIR -name "*.log" -print0 | xargs -0 CMD12
See what the loop would doPut echo in front of the command12
A shortcut, and a shortcut with argumentsalias NAME="CMD", NAME() { CMD "$@"; }, in ~/.bashrc or ~/.zshrc12
What is this command, really?type NAME12

Scripts, cron and timers

ToRunLesson
Start every script#!/bin/bash, then set -euo pipefail13
Make it runnablechmod +x FILE, run with ./FILE, or put it in /usr/local/bin13
Its arguments$1, $2, $# (how many), "$@" (all, each whole)13
Clean up however it endstrap 'rm -f "$tmp"' EXIT13
A safe temporary filetmp=$(mktemp)13
Private files from a scriptumask 07713
Check a scriptbash -n FILE, shellcheck FILE13
A cron jobMIN HOUR DAY MONTH WEEKDAY USER COMMAND >> LOG 2>&1 in /etc/cron.d/NAME13
What cron ransudo journalctl -u cron13
A % in a cron line%, or move the command into a script13
Check a timer schedulesystemd-analyze calendar "--* 02:30:00"13
Turn a timer on, and see itsudo systemctl enable --now NAME.timer, systemctl list-timers13
Run a timer's job nowsudo systemctl start NAME.service13
Back up, and restore, a PostgreSQL databasepg_dump DB | gzip > FILE.sql.gz, zcat FILE.sql.gz | psql -d NEWDB13
Numbers with a leading zerodate +%-S, or $((10#$n))13

First checks, by symptom

ToRunLesson
Anything at allWhat changed? systemctl is-active NAME, sudo journalctl -u NAME -n 5014
502 or 504 from nginxsudo tail /var/log/nginx/error.log, ss -tln, the app's port setting14
Service won't startsystemctl status NAME, the journal from the bottom up, sudo -u USER to test as the service's user14
Can't write, job faileddf -h, then sudo du -ah DIR | sort -h | tail14
Slowuptime against nproc, top, free -h, systemctl status PID14
Settings change broke itsudo nginx -t, sudo sshd -t, sudo visudo -c14
Works inside, not outsidecurl -m 5 from outside, sudo ufw status, sudo journalctl -k | grep "UFW BLOCK"14
Applying a settings changeTest, then reload: sudo nginx -t && sudo systemctl reload nginx14

Setup scripts and audits

ToRunLesson
Install a file with mode and ownerinstall -m 640 -o root -g bookshop SRC DEST15
Are two files identical?cmp -s A B15
A file's mode and ownerstat -c '%a %U:%G' FILE15
Add a line only oncegrep -q LINE FILE || echo LINE >> FILE15
Create a user only onceid NAME || useradd ...15
Create a table only onceCREATE TABLE IF NOT EXISTS ...15
Test, then apply, settingssshd -t then systemctl try-reload-or-restart ssh; nginx -t then systemctl reload nginx, each on its own line15
See invisible characterscat -A FILE; strip \r with sed -i 's/\r$//' FILE15
In a pipe, with pipefailgrep PATTERN > /dev/null, not grep -q15
Build, re-run, rebuild with Vagrantvagrant up, vagrant provision, vagrant destroy -f15
Forget a rebuilt server's old keyssh-keygen -R ADDRESS15

On a Mac

Your Mac's terminal looks like Linux, but its tools come from BSD, a different family (Lesson 1). The ones that differ in this track:

ToOn LinuxOn a Mac
Edit a file in place, no backupsed -i 's/a/b/' FILEsed -i '' 's/a/b/' FILE
A file's permissions as a numberstat -c '%a' FILEstat -f '%OLp' FILE
Which version of a toolsed --versionUsually no --version; check man sed
Services and logssystemctl, journalctlNeither exists: macOS uses launchctl and log
Install softwareaptHomebrew: brew install NAME

When a command from this page fails on your Mac, check which machine you meant to run it on first. If it really is meant for the Mac, this table is the usual reason.