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
sudoprivileges.
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
Navigating and listing
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
Warning
rm -rfwith a variable or a wildcard deletes whatever it expands to, without asking. Always check the path withlsfirst.
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 {} +
Warningnever "fix" a permission problem with
chmod 777. It makes the file writable by every user and process on the server. Find out which user needs access and grant exactly that.
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.
