This is the short list of commands you'll use almost every day on Linux, FreeBSD, or any Unix-flavoured system. Memorise the names, copy the examples, and look up the rest in man when you need it. You don't have to remember the flags — you have to remember the command exists.
Conventions in this guide:
- Anything in
angle-bracketsis a placeholder you substitute. - Lines starting with
#are comments, not commands. - Commands prefixed with
sudoneed administrator rights.
Getting around the filesystem
pwd # print working directory — where am I?
ls # list files in the current directory
ls -lh # long listing, human-readable sizes
ls -la # show hidden files (those starting with .)
cd /etc # change to /etc
cd ~ # go to your home directory (or just: cd)
cd - # go back to the previous directory
Two things to remember:
~means "my home directory" — much shorter than typing the full path.- Tab auto-completes file and directory names. Press it often. Press it twice to see all matches.
Looking at files
cat file.txt # dump the whole file to the screen
less file.txt # scroll through it (q to quit, / to search)
head file.txt # first 10 lines
head -n 20 file.txt # first 20 lines
tail file.txt # last 10 lines
tail -f /var/log/syslog # follow a file as it grows (logs!)
file what-is-this # tell me what kind of file this is
tail -f is one of the most useful commands in the toolkit — keep it open in a window to watch logs in real time. Ctrl+C to stop.
Creating, moving, copying, deleting
mkdir notes # make a directory
mkdir -p projects/2026/may # make nested directories
touch newfile.txt # create an empty file (or update timestamp)
cp source.txt destination.txt # copy a file
cp -r src-dir/ dest-dir/ # copy a directory and everything in it
mv old-name.txt new-name.txt # rename or move
rm file.txt # delete a file
rm -r some-directory/ # delete a directory and its contents
rm -i file.txt # ask before deleting (safer)
Big warning about rm: there's no undo, no Recycle Bin. Once it's gone, it's gone. Get into the habit of using rm -i until you're confident, or use ls first to confirm exactly what you're about to delete.
Finding things
find . -name "*.txt" # find all .txt files in the current tree
find /etc -type f -name "*.conf" # only files (not dirs), name pattern
find . -mtime -7 # modified in the last 7 days
grep "needle" haystack.txt # find lines containing "needle"
grep -i "case-insensitive" file.txt # ignore case
grep -r "search-in-tree" . # recursive — search every file under .
grep -n "pattern" file # show line numbers
grep -v "exclude-this" file # invert: show lines NOT matching
which python3 # what runs when I type "python3"?
whereis ls # show binary + man page locations
grep is probably the command you'll use most often once you're comfortable. It's a verb in unix culture: "let me grep through the logs for that error."
Working with text
wc file.txt # line count, word count, byte count
wc -l file.txt # just lines
sort file.txt # sort lines alphabetically
sort -n numbers.txt # numeric sort
sort -r file.txt # reverse
uniq sorted-file.txt # collapse adjacent duplicate lines
sort file | uniq # the classic pairing
sort file | uniq -c # count how many times each line appeared
cut -d, -f2 data.csv # take the 2nd field, comma-separated
cut -c1-10 file.txt # take characters 1 through 10
tr a-z A-Z < file.txt # translate: lowercase to uppercase
tr -d '\r' < dos-file.txt # delete carriage returns (DOS → unix)
diff file1.txt file2.txt # show what differs between two files
The Swiss army knives are awk and sed — too deep to cover here, but worth knowing they exist:
awk '{print $1}' file # print the first whitespace-separated field
awk -F, '{print $3}' data.csv # 3rd CSV field
sed 's/old/new/g' file # replace all "old" with "new"
sed -i 's/old/new/g' file # in-place — modifies the file directly
Permissions and ownership
ls -l file.txt
# -rw-r--r-- 1 alice staff 120 May 15 14:00 file.txt
# ↑ ↑ ↑ ↑ ↑ ↑
# perms links user grp size name
The permissions string has three triplets: owner, group, everyone-else. Each triplet is r read, w write, x execute, or - for "not allowed."
chmod +x script.sh # make executable
chmod 644 file.txt # rw-r--r-- (the numeric version)
chmod 755 script.sh # rwxr-xr-x — typical for scripts
chmod -R 644 folder/ # apply recursively
sudo chown alice file.txt # change owner
sudo chown alice:staff file # change owner AND group
sudo chgrp wheel file # just change group
Numeric chmod, demystified: each digit is the sum of 4=read, 2=write, 1=execute. So 7 = read+write+execute, 5 = read+execute, 6 = read+write.
Processes
ps # processes started in this terminal
ps aux # everything running on the system
ps aux | grep firefox # find a specific process
top # live process viewer (q to quit)
htop # nicer top — install it if you can
kill 1234 # ask process 1234 to stop politely
kill -9 1234 # forcibly murder it (last resort)
killall firefox # kill all processes named "firefox"
jobs # list background jobs in this shell
& # append to a command to background it
fg # bring last background job to foreground
bg # background a stopped job
nohup long-running-command & # run something that survives logout
Pressing Ctrl+C sends a polite stop signal. Ctrl+Z pauses the running program — type bg to push it into the background or fg to resume.
Pipes and redirection
This is the unix superpower: chaining small commands into pipelines.
ls | wc -l # how many things are in this directory?
cat file | grep error # find error lines in a file
ps aux | grep python | wc -l # how many python processes?
command > out.txt # send standard output to a file (overwrite)
command >> out.txt # append instead
command 2> errors.txt # send error output to a file
command > out.txt 2>&1 # combine both into one file
command &> all.txt # shortcut for the above (bash/zsh only)
command < input.txt # feed a file in as input
xargs # turn input into command arguments
find . -name "*.bak" | xargs rm # delete every .bak file found
The mental model: | is "send the output of the left command as input to the right command." > is "send output to a file instead of the screen." Once those click, half of unix becomes legible.
Compressed files and archives
# tar — the classic archive tool (no compression by default)
tar -cf archive.tar folder/ # create
tar -xf archive.tar # extract
tar -tf archive.tar # list contents
tar -czf archive.tar.gz folder/ # create + gzip-compress
tar -xzf archive.tar.gz # extract gzipped tar
# the flags: c=create, x=extract, t=list, f=filename, z=gzip, j=bzip2, J=xz
# remember: "X-tract Z-ipped File" = -xzf
gzip file.txt # produces file.txt.gz, removes original
gunzip file.txt.gz # the reverse
gzip -k file.txt # keep the original too
zip -r archive.zip folder/ # if you need windows-compatible zip
unzip archive.zip
Network basics
ping example.com # is the host alive? (Ctrl+C to stop)
ping -c 4 example.com # send just 4 pings
curl https://example.com # fetch a URL, dump to screen
curl -O https://example.com/file.tar.gz # save to a file
curl -L https://example.com # follow redirects
curl -I https://example.com # show headers only
wget https://example.com/big-file.iso # download and save
wget -c https://example.com/big-file.iso # continue an interrupted download
ssh user@example.com # log in to another machine
ssh -p 2222 user@host # use a specific port
scp file.txt user@host:/tmp/ # copy a file over ssh
scp -r folder/ user@host:/tmp/ # recursive
ip addr # show network interfaces (Linux)
ifconfig # the older equivalent (still on BSD)
ss -tulpn # listening sockets (Linux)
sockstat -l # the BSD equivalent
System info
uname -a # kernel + hostname + architecture
whoami # who am I logged in as?
id # me, plus my groups and uid/gid
who # who else is logged in
date # current date/time
uptime # how long has the system been up?
df -h # disk usage by filesystem
du -sh folder/ # how big is this folder?
du -sh * | sort -h # size of each thing in current dir, sorted
free -h # memory usage (Linux; FreeBSD has top instead)
lscpu # CPU info (Linux)
sysctl hw # CPU/hardware info (BSD)
neofetch # tidy summary + your distro's ASCII logo
fastfetch # the modern, actively-maintained alternative
neofetch and fastfetch print a one-screen summary of your machine — distro, kernel, uptime, shell, CPU, RAM, GPU — next to your distro's ASCII logo. Handy for "what am I logged into?" and beloved on social media for screenshots. The original neofetch is no longer actively maintained, so most distros now ship fastfetch; either works the same way.
Getting help
man ls # the manual page for ls
man -k network # search manual pages for "network"
apropos copy # same idea — show what's related to "copy"
ls --help # short usage summary (Linux convention)
ls -h # the BSD equivalent of --help on some commands
help cd # bash builtins (not external commands)
type rm # is this a builtin, alias, or binary?
Manual pages look intimidating but they're searchable: type /word inside man to find "word" in the page, n for the next match, q to quit.
Five quality-of-life tricks
- Tab for autocomplete. Always. Press it twice to see options.
- ↑ and ↓ walk through your command history.
- Ctrl+R searches your command history — type any part of an old command and the shell suggests the most recent match.
- Ctrl+L clears the screen (same as typing
clear). - Ctrl+A / Ctrl+E jump to the start / end of the line you're editing.
The honest truth about memorising commands
Nobody knows every flag. Experienced users look up man tar for the millionth time when they need a specific option. What you build over time isn't memory — it's a sense of which command exists for which job — and for the exhaustive catalogue, Unix and Windows alike, see the complete cross-platform command reference. That's the goal here. Once you know "I want to extract this archive" maps to "tar can do that," man tar tells you the rest in under a minute.