Most day-to-day server administration comes down to a few dozen commands: finding and editing files, fixing permissions, managing users and services, reading logs, and checking disk, memory and network. This guide is a practical reference of those commands with realistic examples you can run on Ubuntu 24.04. They work the same on Debian and Rocky Linux unless a note says otherwise.

Prerequisites

To follow along you need:

  • A Linux server, for example a CubePath VPS running Ubuntu 24.04 LTS.
  • A non-root user with sudo privileges.

Every command has a built-in manual. When you need an option that is not shown here, run man command (for example man find) or command --help.

Files and directories

pwd prints the current directory, cd changes it, and ls lists its contents. The -l flag shows permissions, owner, size and date, -a includes hidden files, and -h prints human-readable sizes:

cd /var/log
ls -lah
total 2.1M
drwxrwxr-x  10 root   syslog 4.0K Sep 25 06:25 .
drwxr-xr-x  13 root   root   4.0K Jun 10 12:01 ..
-rw-r-----   1 syslog adm    210K Sep 25 10:14 auth.log
drwxr-sr-x+  4 root   systemd-journal 4.0K Jun 10 12:03 journal
-rw-r-----   1 syslog adm    980K Sep 25 10:14 syslog

cd - returns to the previous directory and cd alone goes to your home directory. ls -lt sorts by modification time, newest first, which is handy for finding the file that just changed.

Creating, copying, moving and deleting

Create a directory, including missing parent directories:

mkdir -p ~/backups/nginx

Copy a file, preserving its permissions and timestamps, and copy a directory recursively:

sudo cp -p /etc/nginx/nginx.conf ~/backups/nginx/nginx.conf.bak
sudo cp -a /etc/nginx ~/backups/nginx/

Move or rename a file with mv:

mv report.txt report-2026-09.txt

Delete files with rm and directories with rm -r. There is no recycle bin, so add -i when you want a confirmation for each file:

rm -i old-report.txt
rm -r ~/tmp/build

Finding files

find searches a directory tree by name, type, size, age and more. Find configuration files named after a service:

sudo find /etc -name '*nginx*'

Find files larger than 500 MB under /var, a common first step when a disk fills up:

sudo find /var -type f -size +500M -exec ls -lh {} +

Find log files not modified in the last 30 days:

sudo find /var/log -type f -name '*.gz' -mtime +30

Once the list looks right, you can add -delete to the same command to remove those files.

Permissions and ownership

Reading permissions

In the output of ls -l, the first column shows the file type and permissions for the owner, group and others: r (read), w (write), x (execute, or enter for directories). In numeric form, read is 4, write is 2 and execute is 1, so 640 means read and write for the owner, read for the group, and nothing for others.

chmod

Make a script executable for its owner:

chmod u+x deploy.sh

Set exact permissions numerically. A private key must be readable only by its owner:

chmod 600 ~/.ssh/id_ed25519

A typical web root uses 755 for directories and 644 for files:

sudo find /var/www/your_domain -type d -exec chmod 755 {} +
sudo find /var/www/your_domain -type f -exec chmod 644 {} +

chown

Change the owner and group of a directory tree, for example so that Nginx and PHP-FPM (running as www-data) can write to an uploads directory:

sudo chown -R www-data:www-data /var/www/your_domain/uploads

Check the result with ls -ld /var/www/your_domain/uploads.

Viewing and searching text

Reading files

cat prints a whole file, which is fine for short files. For long files use less, which lets you scroll, search with /pattern and quit with q:

less /etc/ssh/sshd_config

head and tail show the start or end of a file. tail -f keeps the file open and prints new lines as they are written, which is how you watch a log live:

sudo tail -n 50 /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log

Press CTRL+C to stop following.

grep

grep prints the lines that match a pattern. Search a log case-insensitively and show line numbers:

sudo grep -in 'failed password' /var/log/auth.log

Search recursively through a directory for a setting:

sudo grep -rn 'server_name' /etc/nginx/sites-enabled/

Show only active lines of a configuration file, skipping comments and blank lines:

grep -Ev '^\s*(#|$)' /etc/ssh/sshd_config

grep -c counts matching lines instead of printing them, and -v inverts the match.

Combining commands with pipes

The | operator sends one command's output to the next. These small building blocks answer a lot of questions. For example, the ten IP addresses that made the most requests to Nginx:

sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
   4821 203.0.113.45
   1310 198.51.100.7
    977 192.0.2.19
...

Here awk '{print $1}' extracts the first field (the client IP), sort | uniq -c counts identical lines, sort -rn orders them by count, and head keeps the top ten. wc -l counts the lines it receives, so grep pattern file | wc -l gives the same result as grep -c pattern file.

sed

sed edits text as a stream. The most common use is replacing a string in a file. Preview the change first by printing the result without writing it:

sed 's/worker_connections 768;/worker_connections 1024;/' /etc/nginx/nginx.conf | grep worker_connections

When it looks right, edit the file in place and keep a backup copy with the .bak suffix:

sudo sed -i.bak 's/worker_connections 768;/worker_connections 1024;/' /etc/nginx/nginx.conf

After editing a service's configuration, validate it (here with sudo nginx -t) before reloading the service.

Users and groups

Create a user with a home directory and Bash as the shell, and set a password:

sudo useradd -m -s /bin/bash your_user
sudo passwd your_user

On Ubuntu and Debian, sudo adduser your_user does the same interactively.

Give the user administrative rights by adding it to the sudo group (on Rocky Linux the group is called wheel). The -a flag appends to the existing groups instead of replacing them:

sudo usermod -aG sudo your_user

Check a user's groups and IDs:

id your_user
uid=1001(your_user) gid=1001(your_user) groups=1001(your_user),27(sudo)

Lock an account without deleting it, and remove a user together with their home directory:

sudo usermod -L old_user
sudo userdel -r old_user

Run a single command as another user, or open a root shell when you need several privileged commands in a row:

sudo -u www-data php /var/www/your_domain/artisan cache:clear
sudo -i

Type exit to leave the root shell as soon as you are done.

Processes

ps lists processes. Show every process with its user, CPU and memory usage, sorted by memory:

ps aux --sort=-%mem | head -10

Find processes by name:

pgrep -a nginx
1203 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
1204 nginx: worker process

For a live view, use top (installed everywhere) or htop (friendlier, install it with sudo apt install htop). In top, press M to sort by memory, P to sort by CPU and q to quit.

Stop a process by PID. kill sends SIGTERM, which asks the program to exit cleanly. Use -9 (SIGKILL) only if it does not respond:

kill 4821
kill -9 4821

For anything that runs as a service, use systemctl instead of kill, so systemd knows the service was stopped on purpose.

Services and logs with systemd

systemctl

Check whether a service is running, and see its most recent log lines:

systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Thu 2026-09-25 08:12:44 UTC; 2h 3min ago
...

Start, stop, restart, or reload the configuration without dropping connections (when the service supports it):

sudo systemctl restart nginx
sudo systemctl reload nginx

Enable a service at boot and start it now in one command, or disable it:

sudo systemctl enable --now nginx
sudo systemctl disable --now apache2

List services that failed:

systemctl --failed

journalctl

systemd collects the logs of every service in the journal. Show the logs of one service since the last boot, or follow them live:

sudo journalctl -u nginx -b
sudo journalctl -u nginx -f

Filter by time or priority. This shows errors and worse from the last hour:

sudo journalctl --since "1 hour ago" -p err

Check how much disk the journal uses and shrink it if needed:

journalctl --disk-usage
sudo journalctl --vacuum-size=500M

Disk, memory and load

Disk space

df -h shows free space per mounted file system. When a partition is almost full, du shows which directories use the space:

df -h
sudo du -xh --max-depth=1 /var | sort -h
4.0K    /var/mail
...
820M    /var/cache
2.3G    /var/lib
3.4G    /var/log
6.6G    /var

The -x flag keeps du on one file system. Repeat the command on the largest directory until you find the culprit.

lsblk lists disks and partitions and where they are mounted, which is the first command to run after attaching a new volume:

lsblk -f

Memory

free -h
               total        used        free      shared  buff/cache   available
Mem:           3.8Gi       1.2Gi       410Mi        12Mi       2.4Gi       2.6Gi
Swap:          1.0Gi          0B       1.0Gi

Look at the available column, not free. Linux uses spare memory as file cache (buff/cache) and releases it when applications need it.

Load and uptime

uptime
 10:15:32 up 12 days,  3:41,  1 user,  load average: 0.42, 0.37, 0.30

The three load averages cover the last 1, 5 and 15 minutes. As a rough guide, a load consistently above the number of CPU cores (shown by nproc) means processes are waiting for CPU or disk.

To tell CPU pressure from disk pressure, vmstat 2 5 prints five samples two seconds apart; a high wa column means processes wait on I/O. For per-disk detail install the sysstat package and run iostat -xz 2.

Networking

Interfaces and routes

Show IP addresses and the routing table:

ip -br addr
ip route
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             203.0.113.10/24 2001:db8::10/64
default via 203.0.113.1 dev eth0 proto static

ip replaces the older ifconfig and route commands, which are not installed by default on current distributions.

Listening ports

ss shows sockets. List every TCP and UDP port a process is listening on, with the process name:

sudo ss -tulpn
Netid State  Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp   LISTEN 0      511          0.0.0.0:80        0.0.0.0:*     users:(("nginx",pid=1203,fd=6))
tcp   LISTEN 0      4096         0.0.0.0:22        0.0.0.0:*     users:(("sshd",pid=880,fd=3))

This answers "is my service actually listening, and on which address?" before you start debugging firewalls. ss replaces netstat, which is no longer installed by default.

Connectivity and DNS

Test reachability and latency, and trace the path to a host:

ping -c 4 1.1.1.1
tracepath example.com

For a continuously updated per-hop report, install mtr (sudo apt install mtr-tiny) and run mtr example.com.

Query DNS records with dig (package bind9-dnsutils on Ubuntu and Debian, bind-utils on Rocky Linux):

dig +short A your_domain
dig +short MX your_domain

HTTP checks and downloads

Fetch only the response headers of a URL to check status codes, redirects and TLS:

curl -I https://your_domain
HTTP/2 200
server: nginx
content-type: text/html

Download a file, following redirects and failing on HTTP errors:

curl -fLO https://example.com/file.tar.gz

Packages and system information

Update and install software with the distribution's package manager. On Ubuntu and Debian:

sudo apt update
sudo apt upgrade
sudo apt install htop

On Rocky Linux and AlmaLinux:

sudo dnf upgrade
sudo dnf install htop

Check the distribution, kernel and hostname:

cat /etc/os-release
uname -r
hostnamectl

Read kernel messages, for example after a disk error or an out-of-memory kill:

sudo dmesg -T | tail -30

See who is logged in now and the recent login history:

who
last -n 10

Conclusion

These commands cover most of what you will do on a Linux server: navigating and editing files, controlling access, running services, reading logs and diagnosing disk, memory and network problems. Practise them on a test server until they are second nature, then continue with the guides on package management with APT and DNF, configuring a firewall with UFW, and securing SSH access.