01Files & navigation

Move around a filesystem and find things fast.

pwd                          # print the current directory
ls -lah                      # long listing, human sizes, incl. hidden files
cd -                         # jump back to the previous directory
tree -L 2                    # directory tree, 2 levels deep
find /etc -name "*.conf"     # find files by name under a path
find . -type f -mmin -15     # files modified in the last 15 minutes
stat /etc/hosts              # size, owner, and timestamps of a file
realpath ./link              # resolve a path/symlink to its absolute form
$ ls -lah
total 24K
drwxr-xr-x  3 alban alban 4.0K Jul 28 09:14 .
drwxr-xr-x 18 alban alban 4.0K Jul 27 21:02 ..
-rw-------  1 alban alban 1.7K Jul 28 09:10 id_ed25519
-rw-r--r--  1 alban alban 3.2K Jul 20 14:33 notes.md

02Viewing & following files

Read configs and watch logs as they change.

cat /etc/os-release          # dump a small file to the screen
less /var/log/syslog         # page through a large file (q to quit, / to search)
head -n 20 access.log        # first 20 lines
tail -n 50 access.log        # last 50 lines
tail -f /var/log/syslog      # follow a log live as it grows
watch -n 2 'ip -br a'        # re-run a command every 2s and show the output
command | tee out.txt        # print AND save output at the same time
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="22.04.4 LTS (Jammy Jellyfish)"
ID=ubuntu
PRETTY_NAME="Ubuntu 22.04.4 LTS"

03Search & text processing

The glue of the shell: filter, extract, and reshape text and logs.

grep -Rin "timeout" /etc      # recursive, case-insensitive search with line numbers
grep -c "404" access.log      # count matching lines
awk '{print $1}' access.log   # print the first whitespace field (e.g. client IP)
awk -F: '{print $1}' /etc/passwd   # split on ":" and print field 1
sed -n '10,20p' file          # print lines 10-20
sed 's/foo/bar/g' in > out    # substitute text (stream editor)
cut -d, -f2 data.csv          # cut the 2nd comma-separated field
sort access.log | uniq -c | sort -rn   # top repeated lines (frequency)
wc -l access.log              # count lines
... | xargs -I{} cmd {}       # turn stdin into arguments for another command
$ grep -Rin "timeout" /etc/systemd
/etc/systemd/system.conf:38:#DefaultTimeoutStartSec=90s
/etc/systemd/system.conf:39:#DefaultTimeoutStopSec=90s

04Interfaces & routing

Inspect and change L2/L3 state. ip replaces the old ifconfig/route.

ip -br a                     # brief: interfaces, state, and IPs
ip a show eth0               # full addressing detail for one interface
ip r                         # the routing table
ip r get 10.0.0.1            # which route/interface would reach a destination
ip link set eth0 up          # bring an interface up (or 'down')
ip neigh                     # ARP / neighbor table
ethtool eth0                 # link speed, duplex, driver info
nmcli device status          # NetworkManager view of devices (many distros)
$ ip -br a
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             192.0.2.20/24 fe80::5054:ff:fe12:3456/64

05Connectivity & DNS

Prove reachability, trace the path, and resolve names.

ping -c 4 example.com        # 4 echo requests then stop
traceroute example.com       # hop-by-hop path to a host
mtr example.com              # live traceroute + loss/latency per hop
dig +short A example.com     # concise DNS A-record lookup
dig @1.1.1.1 example.com MX  # query a specific resolver for a record type
host example.com             # quick forward/reverse resolution
curl -I https://example.com  # fetch just the HTTP response headers
curl -s ifconfig.me          # print your public IP (via a web service)
wget -q -O file.iso URL      # download a file quietly to a path
$ dig +short A example.com
203.0.113.10

Caviar — stamp every ping reply with the time. Pipe ping through a while read loop so each reply carries a timestamp — invaluable for pinning down exactly when a flaky link drops (leave it running and check the gaps):

ping6 2001:4860:4860::8888 | while read pong; do echo "$(date): $pong"; done   # IPv6 · target = Google Public DNS
ping4 8.8.8.8 | while read pong; do echo "$(date): $pong"; done                # IPv4 · target = Google Public DNS

06Sockets & packet capture

See what's listening, what's connected, and what's on the wire.

ss -tulpn                    # listening TCP/UDP ports + owning PIDs
ss -tan state established    # established TCP connections
tcpdump -ni eth0 port 443    # sniff HTTPS on eth0 (no name resolution)
tcpdump -ni eth0 host 10.0.0.5 and icmp   # filter by host + protocol
tcpdump -ni eth0 -w cap.pcap # write a capture to open later in Wireshark
nc -vz example.com 443       # test whether a TCP port is open
nmap -sT -p 22,80,443 10.0.0.0/24   # port-scan a range (authorized only)
iftop -i eth0                # live per-connection bandwidth on an interface
$ ss -tulpn
Netid State  Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp   LISTEN 0      128    0.0.0.0:22         0.0.0.0:*         users:(("sshd",pid=812,fd=3))
tcp   LISTEN 0      511    0.0.0.0:443        0.0.0.0:*         users:(("nginx",pid=999,fd=6))
udp   UNCONN 0      0      0.0.0.0:161        0.0.0.0:*         users:(("snmpd",pid=740,fd=6))

07Remote access & file transfer

Get onto boxes and move data between them securely.

ssh user@example.com         # open a remote shell
ssh -J jump user@target      # hop through a bastion/jump host
ssh -L 8080:localhost:80 user@host   # local port-forward (tunnel)
ssh-keygen -t ed25519        # generate a modern SSH key pair
ssh-copy-id user@example.com # install your public key on a server
scp file user@host:/tmp/     # copy a file over SSH
rsync -avz --progress src/ user@host:/dst/   # efficient, resumable sync
sftp user@example.com        # interactive file transfer over SSH
$ ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Your identification has been saved in /home/alban/.ssh/id_ed25519
Your public key has been saved in /home/alban/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:Xr4Bd0m9c1EXAMPLEfingerprintPLACEHOLDER0123 alban@host

08Processes & services

Find what's running, control it, and read what systemd services are doing.

ps aux --sort=-%cpu | head   # top CPU consumers
top          # or: htop        # live process view
kill -TERM 1234              # ask a PID to stop (use -9 only as last resort)
pkill -f "python app.py"     # kill by matching command line
systemctl status sshd        # is a service running? recent logs
systemctl restart nginx      # restart a service (enable = start on boot)
journalctl -u nginx -f       # follow one service's logs
journalctl -p err -b         # error-level messages since last boot
nohup ./long-job.sh &        # keep a job running after you log out
$ systemctl status sshd
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; preset: enabled)
     Active: active (running) since Mon 2026-07-27 08:12:03 UTC; 1 day ago
   Main PID: 812 (sshd)
      Tasks: 1 (limit: 18919)

09System health & performance

Answer "is the box healthy?" in under a minute.

uname -a                     # kernel and architecture
uptime                       # load averages + how long it's been up
free -h                      # memory and swap usage
df -h                        # disk space per filesystem
du -sh *                     # size of each item in the current dir
dmesg -T | tail              # recent kernel messages (link flaps, OOM, disks)
vmstat 1 5                   # CPU/memory/IO snapshots, 5x at 1s intervals
lscpu                        # CPU model, cores, virtualization flags
$ free -h
               total        used        free      shared  buff/cache   available
Mem:            15Gi       3.1Gi       8.4Gi       220Mi       3.9Gi        11Gi
Swap:          2.0Gi          0B       2.0Gi

10Users, permissions & firewall

Who you are, what you can touch, and what the host lets in.

id                           # your UID/GID and group memberships
sudo -l                      # what you're allowed to run as root
chmod 640 secret.key         # set permissions (owner rw, group r, others none)
chmod +x script.sh           # make a file executable
chown user:group file        # change ownership
passwd                       # change your password
ufw status verbose           # host firewall state (Debian/Ubuntu)
ufw allow 22/tcp             # open a port (RHEL: firewall-cmd --add-port=22/tcp)
iptables -L -n -v            # list packet-filter rules (nft: nft list ruleset)
$ id
uid=1000(alban) gid=1000(alban) groups=1000(alban),27(sudo),4(adm)

11Shell productivity & automation

The operators and habits that turn one-off commands into repeatable work.

cmd1 | cmd2                  # pipe: send output of one command into the next
cmd > out.txt                # redirect stdout to a file (>> to append)
cmd 2>&1 | tee log.txt        # capture stdout AND stderr, on screen + to a file
cmd1 && cmd2                  # run cmd2 only if cmd1 succeeded ( || = on failure )
for h in web1 web2; do ssh $h uptime; done   # loop over hosts
crontab -e                   # schedule jobs (e.g. "*/5 * * * * /path/check.sh")
alias ll='ls -lah'           # shortcut you can add to ~/.bashrc
history | grep ssh           # find a command you ran earlier
man ss   # or: ss --help      # the manual — your first stop for any flag
$ history | grep ssh
  482  ssh alban@web1
  501  ssh-copy-id alban@web1
  517  history | grep ssh

12Where to go next

Keep this page open in a tab while you work — muscle memory comes from use, not memorization. When you outgrow a one-liner, wrap it in a script and let a scheduler or pipeline run it for you; that's the same jump from typing commands to driving APIs and infrastructure as code. Back to the Knowledge Base.