Linux Commands Every DevOps Engineer Should Know

There's a version of this article that just lists commands with a one liner description. This isn't that.
This blog has real examples that reflect what comes up in production, and every command here has a practical context. Some of them you'll use everyday and a few you'll use once and then when required.
Who This Is For
If you're entering DevOps, working in cloud infrastructure, or managing Linux servers in any capacity then this is for you. The commands are split into 9 categories that map to real scenarios: navigating filesystems, debugging processes, chasing log errors, managing deployments, locking down security, and more.
Assumes you're comfortable in a terminal.
1. File & Directory
These are the commands you'll run dozens of times a day. The goal here isn't just to know them.
ls -la
The standard ls shows you files. ls -la shows you everything, hidden files (dotfiles), permissions, ownership, file size, and last modified timestamp. In a DevOps context, the permissions and ownership columns are what you're actually reading.
ls -la /etc/nginx/
Run this before touching any config file on a server you've just SSHed into. Know who owns what before you change anything.
find
One of the most powerful commands in Linux. find searches your filesystem with filters, by name, by type, by size, by how recently a file was modified. No GUI, no guessing.
find /var/log -name "*.log" -mtime -7
This finds every .log file under /var/log that was modified in the last 7 days. Combine with -size +100M to find large files eating your disk, or -type d to list only directories.
cp -r
Copies a directory and everything inside it recursively. Simple but critical, always back up config files before editing them in production.
cp -r /etc/nginx /etc/nginx_backup
Before you change an nginx config, run this. If you break something, you have a clean copy to restore from without needing a rollback pipeline.
rsync
rsync is precise. It only transfers files that have changed, making it far faster for large directories. It works locally and over SSH, supports compression, and shows progress. Standard for deployment syncing and backup jobs.
rsync -avz /var/www/html/ user@192.168.1.10:/var/www/html/
The flags: -a preserves permissions and timestamps, -v shows verbose output, -z compresses during transfer. Add --dry-run first to preview what will actually sync before committing.
tar
Archives multiple files into one compressed package. Used constantly for backups, transferring config bundles, and bundling deployment artifacts.
tar -czf backup_$(date +%F).tar.gz /etc/nginx /etc/ssl
The $(date +%F) injects today's date into the filename automatically, so each backup is timestamped. To extract: tar -xzf filename.tar.gz. Remember: -c creates, -x extracts, -z uses gzip, -f specifies the filename.
2. Text Processing
Log files, config files, CSVs, command output, almost everything in Linux is plain text. These commands let you slice, search, count, and transform that text without opening a single editor.
grep -rn
grep searches for patterns. Add -r for recursive (searches all files in a directory) and -n to show the line number alongside each match. In DevOps, this is your first move when something breaks and you need to find where an error originates.
grep -rn "ERROR" /var/log/app/
Scans every file under /var/log/app/ for the word ERROR and tells you exactly which file and line it appears on. Pipe it into wc -l to count how many errors exist, or into grep -v to further filter results.
awk
awk processes text line by line, treating each line as a set of columns separated by whitespace (or a delimiter you define). It's a mini programming language, but in practice you'll use it most for extracting specific fields from structured output.
awk '{print \(1, \)9}' /var/log/nginx/access.log
Nginx access logs have a defined structure. Column 1 is the client IP, column 9 is the HTTP status code. This strips everything else out, giving you a clean IP-to-status mapping you can pipe into sort | uniq -c to count responses per status code.
sed
The stream editor. It reads input line by line, applies a transformation, and outputs the result. The most common use is find-and-replace, especially useful when updating config files during deployments without manually opening them.
sed -i 's/localhost/prod-db.internal/g' /etc/app/config.yml
The -i flag edits the file in place. Without -i, sed outputs to stdout, useful for previewing the change before committing it.
cut
Extracts specific fields from each line based on a delimiter. Think of it as a lightweight awk for simple column extraction.
cut -d':' -f1 /etc/passwd
The -d':' sets the delimiter to a colon, -f1 grabs the first field. This gives you a clean list of all usernames on the system, useful for auditing or scripting user management tasks.
wc -l
Counts lines. That's it. But when piped with other commands, it becomes a quick way to quantify anything, how many errors in a log, how many files match a pattern, how many open connections exist.
grep "FAILED" /var/log/auth.log | wc -l
Run this after a suspicious period on your server. If the count is abnormally high, you're likely looking at a brute force attempt.
3. Process & System
When something is consuming too much CPU, holding a port, or refusing to die then these are the commands you reach for.
ps aux
A snapshot of every process currently running on the system, with full details: user, CPU%, memory%, PID, and the full command that launched it.
ps aux | grep nginx
Shows all nginx worker processes with their resource consumption. Tells you immediately if nginx is running, how many workers are active.
kill / killall
kill terminates a process by its PID. killall terminates all processes matching a name. By default both send SIGTERM, a graceful shutdown request. Adding -9 sends SIGKILL, immediate, forceful, no cleanup.
kill -9 3821
killall node
Use kill first, it lets the process clean up after itself. Only escalate to kill -9 when the process is truly unresponsive. killall node is useful after a bad deployment when you want to kill all node instances and restart clean.
pgrep
Finds the PID of a running process by name.
pgrep -l nginx
The -l flag returns both the PID and process name. Clean, fast, scriptable. Use the output directly: kill $(pgrep nginx) kills all nginx processes in one command.
top / htop
top is the built-in live process monitor, CPU, memory, load average, all running processes, refreshed every few seconds. htop is the modern version with colors, mouse support, and better keyboard navigation. Install htop if it's not there, it's worth it.
htop
Inside htop: F6 to sort by CPU or memory, F9 to kill a selected process, F5 for tree view showing parent child relationships. During a high load incident, htop is usually the first thing you open.
lsof
Lists every open file on the system and which process holds it.
lsof -i :8080
Shows exactly which process is listening on or connected to port 8080. When a deployment fails because the port is already in use, this tells you what's holding it and gives you the PID to kill.
4. Disk & Storage
Disk problems in production are silent until they're catastrophic. Running out of space can crash databases, stop log writes, corrupt files, and bring down services. These commands keep you informed before that happens.
df -h
Shows how much disk space is available and used across all mounted filesystems.
df -h
Check the Use% column. Anything above 80% needs attention. Anything above 90% is urgent. /var and / filling up are the most common culprits in disk related production incidents.
du -sh
Where df shows filesystem level usage, du shows directory level usage. -s summarises (total only), -h makes it human-readable.
du -sh /var/log/* | sort -rh | head -10
Lists the 10 biggest items inside /var/log, sorted largest first. Run this when df -h shows a filesystem is full, it tells you exactly what's eating the space so you can decide what to clean or rotate.
lsblk
Lists all block devices, disks, partitions, LVM volumes and their mount points in a clean tree structure.
lsblk -f
The -f flag adds filesystem type and mount point info. Use this when a new EBS volume or disk has been attached and you need to identify its device name before mounting it.
mount / umount
Attaches a filesystem to a directory (mount point) so you can access its contents, or safely detaches it.
mount /dev/sdb1 /mnt/data
Before running this, use lsblk -f to confirm the device name.
iostat
Reports CPU utilization and disk I/O statistics, reads and writes per second, throughput, and wait times per device. Critical for diagnosing whether slow application performance is caused by disk bottlenecks.
iostat -xz 2 5
-x shows extended stats, -z omits idle devices, 2 5 samples every 2 seconds five times. Watch the %util column, consistently above 80% on a device means that disk is saturated and likely causing latency downstream.
5. Networking
Connectivity issues, DNS misconfigurations, unexpected open ports, networking problems show up constantly. These commands cover basic connectivity checks, DNS debugging, and secure file transfer.
curl
The most versatile networking command in the toolkit. Transfers data to or from a URL. Used for testing APIs, checking HTTP response headers, downloading files, and probing endpoints.
curl -I https://yourdomain.com
The -I flag fetches only HTTP headers, status code, content type, cache control, server type. Add -v for full verbose output including the TLS handshake.
ss -tuln
The modern replacement for netstat. Shows all active TCP and UDP sockets. In DevOps, the most common use is confirming which ports are open and listening.
ss -tuln
Flags: -t TCP, -u UDP, -l listening only, -n numeric. Use it after a deployment to verify all services started on the right ports.
ping / traceroute
ping checks if a host is reachable. traceroute maps every network hop between your server and a destination showing you where packets slow down or drop.
traceroute api.github.com
When your application can't reach an external service, ping first to confirm basic connectivity. If ping works but latency is high, traceroute narrows down which hop is responsible.
dig
DNS lookup tool. More detailed and scriptable than nslookup. Query specific record types, see TTLs, check which nameserver responded.
dig A yourdomain.com +short
+short strips everything except the answer, just the IP the domain resolves to. Remove +short when you need TTLs, the responding nameserver, and the full query chain.
scp
Secure copy over SSH. Transfers files between local and remote machines, encrypted. Simple and reliable with no additional software needed.
scp -r user@192.168.1.10:/var/backups/db ./local-backups/
-r copies recursively. Syntax is always source destination, remote paths written as user@host:/path. For large or frequent transfers, rsync is usually better, but scp is perfect for quick one off copies.
6. Security & Permissions
Security in Linux is primarily handled through file permissions, SSH configuration, firewall rules, and certificate management. These five commands cover the essentials that come up in everyday DevOps work.
chmod / chown
chmod sets who can read, write, or execute a file. chown sets ownership. Both are critical when deploying applications, setting up SSH keys, or managing web server files.
chmod 600 ~/.ssh/id_rsa
chown -R www-data:www-data /var/www/html
SSH will refuse to use a private key with permissions other than 600, and for good reason. The chown command recursively transfers ownership of web files to the web server user so nginx or apache can serve them correctly.
ssh-keygen
Generates SSH public/private key pairs. The public key goes on the server (~/.ssh/authorized_keys), the private key stays with you. No more passwords for server authentication.
bash
ssh-keygen -t ed25519 -C "deploy-key-prod"
ed25519 is the modern algorithm, shorter, faster, more secure than RSA 2048. The -C flag adds a label to help identify the key later. For CI/CD pipelines, generate a dedicated deploy key per environment. Never reuse keys across environments.
ufw
The Uncomplicated Firewall, a frontend for iptables that makes managing firewall rules approachable. Standard on Ubuntu based systems.
ufw allow from 10.0.0.0/8 to any port 22
Allows SSH only from your internal network while blocking all external SSH access. Always verify your own IP is covered before enabling ufw on a remote server, or you'll lock yourself out. Use ufw status verbose to review all active rules.
openssl
Inspecting certs, testing secure connections, generating keys, verifying certificate chains.
openssl req -new -newkey rsa:2048 -nodes -keyout private.key -out request.csr
Requesting SSL certificate and generating key + CSR together.
sudo -l
Lists exactly which commands a user is permitted to run with elevated privileges, according to sudoers configuration.
sudo -l -U deploy
Before your deploy user ever touches a production server, run this and verify it can only execute what it absolutely needs to. Principle of least privilege: give it nothing more than required.
7. Logs & Monitoring
Logs are how servers communicate with you. The ability to read, search, filter, and monitor them efficiently in real time is one of the most important practical skills in DevOps.
journalctl
The query interface for systemd's journal, centralized logs on any modern Linux system running systemd.
journalctl -u nginx -f --since "1 hour ago"
-u nginx filters to nginx only, -f follows in real time, --since "1 hour ago" limits to recent entries. Run this during a deployment to see every request, error, and reload event as it happens.
tail -f
Streams the end of a file in real time as new content is written. The classic go to for watching application log files.
tail -f /var/log/app/error.log
Pair with grep to cut through noise: tail -f /var/log/app/error.log | grep -i "exception" gives you only exception lines as they appear. Use tail -n 100 without -f for a quick recent-history check.
watch
Runs any command repeatedly at a set interval and refreshes the output in place.
watch -n 2 'ss -tuln | grep LISTEN'
Refreshes listening ports every 2 seconds. Use it while starting services to confirm they come up on the right ports. Works with anything: watch df -h, watch free -h, watch kubectl get pods.
dmesg
Prints messages from the kernel ring buffer as what happened at a hardware and driver level, especially during boot and when devices are attached or detached.
dmesg | grep -i error | tail -20
First place to look when a server behaves strangely at a hardware level, disk errors, OOM kills, filesystem problems. Use dmesg -T to add human readable timestamps, which makes correlating kernel events with application incidents much easier.
logrotate
Manages automatic rotation, compression, and deletion of log files on a schedule. Without it, long running servers accumulate logs that eventually fill the disk.
logrotate -d /etc/logrotate.d/nginx
The -d flag is a dry run which shows exactly what logrotate would do without actually doing it. Always run this after writing or modifying a logrotate config to verify your rules before trusting them in production.
8. Automation & Scheduling
DevOps is fundamentally about replacing manual, repetitive work with automated, reliable processes. These commands are the building blocks of that.
crontab -e
Opens the cron table for editing. Define scheduled jobs using cron syntax: minute, hour, day of month, month, day of week, then the command to run.
0 2 * * * /opt/scripts/dbbackup. sh >> /var/log/dbbackup. log 2>&1
Run the database backup script every day at 2 AM, and log both output and errors into /var/log/dbbackup. log
nohup
Runs a command that keeps running even after the terminal session that launched it is closed. Without it, processes launched in an SSH session are killed when the connection drops.
bash
nohup python3 app.py > app.log 2>&1 &
The & puts the process in the background. > app.log 2>&1 redirects both stdout and stderr to a log file.
tmux
A terminal multiplexer that creates named, persistent sessions with multiple windows and panes.
tmux new -s deploy
Inside tmux: Ctrl+B then % splits vertically, Ctrl+B then " splits horizontally, Ctrl+B then d detaches without killing the session.
xargs
Takes output from one command and passes it as arguments to another. It bridges commands that produce lists of items with commands that need to act on those items.
find /tmp -name "*.tmp" -mtime +7 | xargs rm -f
find outputs a list of file paths. xargs takes each one and passes it to rm -f. Without xargs you'd need a loop.
env
Displays all current environment variables, or runs a command with specific variables injected without modifying the global environment.
env | grep -i aws
The first command verifies credentials and config are set before running something that depends on them.
9. Git
Git is a terminal first tool. Most engineers know add, commit, and push. The commands below are what separate comfortable Git users from engineers who can navigate any repository situation confidently.
git log --oneline
The default git log is verbose. --oneline condenses each commit to a single line.
git log --oneline --all
Run this in any unfamiliar repository to understand the branch structure before touching anything.
git stash
Saves your current uncommitted changes to a temporary stack, leaving you with a clean working directory.
git stash push -m "WIP: refactor deploy script"
The -m flag labels your stash. git stash list shows all stashed entries.
git diff
Shows exact line-by-line differences between two states, working directory vs staging, staging vs last commit, or any two branches or commits.
git diff main..feature/new-pipeline
Run this before opening a pull request. git diff HEAD~3 compares current state against 3 commits ago.
git bisect
When a bug exists now but didn't in a previous version, git bisect performs a binary search through commit history to find the exact commit that introduced it.
git bisect start
git bisect bad # current state is broken
git bisect good v1.4.0 # this version was working
Git checks out the midpoint commit. You test it, mark it good or bad, and Git halves the range again. On a history of 1,000 commits this takes about 10 steps. End with git bisect reset to return to your original position.
git cherry-pick
Applies the changes from one specific commit onto your current branch, without merging the entire branch it came from. Standard for applying hotfixes across multiple branches.
git cherry-pick a3f5c91
Find the hash from git log --oneline, cherry-pick it, and the changes land on your current branch as a new commit. Use git cherry-pick a3f5c91..b7e2d44 to pick a range of commits at once.
Putting It All Together
The real power isn't in any single command, it's in combining them. A few practical examples:
# Find the 10 largest log files modified this week
find /var/log -name "*.log" -mtime -7 | xargs du -sh | sort -rh | head -10
# Find the top 20 IP addresses making the most requests to your NGINX server
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# Watch memory usage of a specific process, live
watch -n 3 'ps aux | grep node | grep -v grep'
# Find who is holding a port and kill it
lsof -i :3000 | sed '1d' | awk '{print $2}' | xargs kill -9
Each of these is a pipeline, small, focused commands chained to do something no single command could do alone. That's the Unix philosophy, and it's why Linux remains the operating system of choice for infrastructure work.
What's Next
These 45 commands cover the practical foundation. Natural next steps from here:
Shell scripting - turning these commands into repeatable, automated scripts
systemd & service management - going deeper on how Linux manages processes at boot and runtime
Docker commands -
docker exec,docker logs,docker inspectfollow these same mental modelsKubernetes CLI -
kubectlborrows heavily from the same patterns you've built here
The terminal is the interface that underlies all of it. Time spent getting comfortable here pays across every tool built on top of it.
Thanks for reading !
If you found this helpful, give it a like.
Follow Bala for more.



