When I first got into cloud computing some 5yrs ago, I avoided the CLI like it owed me money. I'd click around the console, doing things the slow way, telling myself the GUI was "just as good." It wasn't.
The truth is, if you're serious about working in the cloud whether you're provisioning infrastructure with Terraform, debugging a failing container at 2am, or automating deployments with Ansible you need to be comfortable in the terminal.
The CLI isn't just faster, it's often the only way.
The good news? Bash has a smaller learning curve than most programming languages. it would take you a short amount of time to become a pro in Bash than it would Python.
This guide is designed to take you from nervous about the terminal to actually preferring it.
We'll cover the essential commands grouped by category, with real-world cloud examples alongside each one.
Note: These are bash commands, native to Linux. If you're using Azure Cloud Shell in PowerShell mode, some of these won't apply directly switch to bash mode or check the Azure CLI equivalents.
Before We Start: The Golden Rules of the CLI
-
The CLI is case-sensitive.
lsandLSare completely different. Stick to lowercase unless told otherwise. -
Ctrl + Cbreaks any continuously running process. -
Ctrl + Zsuspends a process (sends it to background). -
Tabauto-completes commands and file paths — use it constantly. -
↑arrow cycles through your command history.
1. Navigation & Directory Management
These are the commands you'll type hundreds of times a day.
pwd
Print Working Directory. Shows exactly where you are in the file system. Run this whenever you're disoriented.
ls
Lists the contents of the current directory. One of the most-used commands in existence.
ls -l
Long-format listing. Shows file type, permissions, owner, size, and timestamp. Essential for auditing files on a cloud VM.
ls -lt
Lists files sorted by timestamp (newest first). Useful for finding what recently changed on a server.
ls -lS
Lists files sorted by size (largest first). Great for hunting down what's eating up your disk.
ls -la
Lists all files including hidden ones (files that start with .). You'll use this constantly — things like .env, .ssh, and .bashrc are all hidden.
cd /path/to/directory
Change Directory. Use cd .. to go up one level, cd ~ to return to your home directory, and cd - to go back to the previous directory.
mkdir my-project
Make Directory. Creates a new folder. Use mkdir -p /parent/child/grandchild to create nested directories in one shot — very handy when scaffolding project structures.
rmdir empty-folder
Removes an empty directory. For non-empty directories, use rm -rf (carefully!).
2. Working with Files
cat filename.txt
Prints the entire file content to your terminal. Perfect for quick checks on config files, log snippets, or cloud-init scripts.
head -n 20 filename.log
Shows the first 20 lines of a file. Swap 20 for any number. Great for peeking at the start of large log files without loading the whole thing.
tail -n 50 filename.log
Shows the last 50 lines of a file. Indispensable for checking recent log entries.
tail -f /var/log/syslog
Follows a file in real time — new lines print as they're written. The go-to command for watching live logs on a running server.
less filename.txt
Opens a file one page at a time. Better than cat for large files. Navigation keys:
-
Space— next page -
b— previous page -
↑ / ↓— line by line -
q— quit
cp source.txt destination.txt
Copy a file. Use cp -r source-dir/ dest-dir/ to copy an entire directory recursively — useful when duplicating configuration directories.
mv oldname.txt newname.txt
Move or rename a file. Moving files between directories or renaming config files before applying changes is a daily task in cloud work.
rm filename.txt
Permanently delete a file. Use rm -rf directory/ to delete a directory and everything inside it. There's no recycle bin — double-check before running this.
touch newfile.txt
Creates an empty file, or updates the timestamp of an existing one. Often used to create placeholder files or trigger file-watching scripts.
ln -s /path/to/original linkname
Creates a symbolic link (shortcut). Useful for pointing multiple config locations to a single source of truth.
file mystery-file
Tells you what type a file is regardless of its extension. Handy when you get an undocumented artifact from a pipeline.
3. Searching & Filtering
grep "error" app.log
Searches a file and returns every line containing the string "error". One of the most powerful commands for log analysis.
grep -r "DATABASE_URL" /etc/
Recursive search through an entire directory. Use this to find where a config value is set across a server.
grep -i "warning" app.log
Case-insensitive search. Catches "Warning", "WARNING", "warning" all at once.
grep -n "timeout" nginx.conf
Returns matching lines with their line numbers. Makes it easy to jump straight to the problem in an editor.
grep -v "DEBUG" app.log
Inverts the match — returns lines that do not contain "DEBUG". Useful for filtering out noisy log entries.
find /var/log -name "*.log" -mtime -1
Find all .log files in /var/log modified in the last 1 day. The find command is incredibly powerful for locating files by name, type, size, age, or permissions.
find / -size +100M
Find all files larger than 100MB. Run this when your disk is full and you need to know why.
locate filename
Faster than find — uses a pre-built index. Update the index with sudo updatedb.
which python3
Shows the full path to an executable. Use this to confirm which version of a tool is actually being used when you have multiple installed.
4. Piping & Redirection
Piping is where bash gets truly powerful. It lets you chain commands together, feeding the output of one into the input of the next.
command1 | command2
The pipe | sends the output of command1 as input to command2.
Real-world example: Find all error lines in a log and count them:
grep "ERROR" app.log | wc -l
Another example: List running processes and filter for a specific one:
ps aux | grep nginx
command > output.txt
Redirects output to a file, overwriting it. Use >> to append instead of overwrite.
command 2> errors.txt
Redirects stderr (error output) to a file. Useful for capturing errors from scripts.
command > output.txt 2>&1
Redirects both stdout and stderr to the same file. The standard pattern for capturing all output from a cron job or automated script.
sort filename.txt | uniq -c | sort -rn
A classic pipe chain: sort lines → count unique occurrences → sort by count descending. Great for finding the most frequent entries in a log.
5. Permissions & Ownership
Understanding permissions is critical when deploying on cloud VMs or managing shared resources.
chmod 644 config.yml
Change permissions of a file. 644 means owner can read/write, group and others can only read. The classic permission for config files.
chmod 600 ~/.ssh/id_rsa
Restricts your SSH private key so only you can read it. SSH will refuse to use a key file with too-open permissions.
chmod +x deploy.sh
Makes a script executable. You'll do this every time you create a new bash script.
chown ubuntu:ubuntu /var/www/html
Change ownership of a file or directory. Specify user:group. Use chown -R to apply recursively to a whole directory.
ls -l
Review the permission string: -rwxr-xr-- breaks down as: file type, owner perms (rwx), group perms (r-x), others perms (r--).
umask 022
Sets the default permissions for newly created files. 022 means files are created as 644 and directories as 755.
6. Users, Sessions & Sudo
whoami
Prints your current username. Run this first when you SSH into an unfamiliar server to confirm who you're logged in as.
sudo command
Superuser do. Runs a command with root/admin privileges without switching users. Most system-level operations require this.
sudo su -
Switches you to the root user session entirely. Use with caution — you can do irreversible damage as root.
su - otheruser
Switch user to another account, loading their environment. Use exit to return to your original session.
passwd
Change your password. Admins can change any user's password with passwd username.
id
Shows your user ID (UID), group ID (GID), and all group memberships. Useful for debugging permission issues.
last
Shows the login history for all users. Use this to audit who has been accessing a server.
w
Shows who is currently logged in and what they're doing. A quick security check.
7. Process Management
ps aux
Lists all running processes on the system with detailed info including user, CPU%, memory%, and command.
ps aux | grep nginx
Find a specific process by name. The standard way to check if a service is running.
top
Real-time, interactive process viewer. Shows CPU and memory usage live. Press q to quit, k to kill a process by PID.
htop
A better, more visual version of top. Install it with sudo apt-get install htop.
kill 1234
Send a termination signal to process with PID 1234. Get the PID from ps aux.
kill -9 1234
Force kill a process — non-ignorable. Use this when a regular kill doesn't work.
pkill nginx
Kill processes by name instead of PID. More convenient when you know the service name.
nohup ./script.sh &
Runs a script in the background and keeps it running even after you log out. The & puts it in the background, nohup prevents it from dying when your session ends.
jobs
Lists background jobs running in the current session.
bg %1
Resume a suspended job in the background. Use fg %1 to bring it back to the foreground.
8. Networking & Connectivity
ping google.com
Tests basic network connectivity and measures latency. The first thing to run when troubleshooting connectivity on a cloud VM.
curl -I https://example.com
Fetches just the HTTP headers from a URL. Use this to check if a web service is responding and what status code it returns.
curl -X POST https://api.example.com/endpoint \
-H "Content-Type: application/json" \
-d '{"key": "value"}'
Make an HTTP POST request with JSON data. Essential for testing APIs and webhooks directly from the command line.
wget https://example.com/file.tar.gz
Downloads a file from the internet. Unlike curl, wget saves to disk by default and supports resuming interrupted downloads.
netstat -tuln
Shows all open ports and listening services. Use this to confirm your app is bound to the right port after deployment.
ss -tuln
The modern replacement for netstat. Faster and more detailed.
traceroute google.com
Traces the network path to a destination, showing every hop. Invaluable for diagnosing where a network issue is occurring.
nslookup myapp.example.com
DNS lookup — resolves a hostname to an IP. Use this to verify DNS propagation after updating records.
dig myapp.example.com
More detailed DNS lookup than nslookup. Shows TTLs, record types, and the responding nameserver.
ifconfig
Shows network interface configuration (IP addresses, etc.). On newer systems, use ip addr instead.
ip addr
The modern way to view network interfaces and IP addresses.
9. SSH & Key Management
SSH is how you access virtually every cloud VM. Know these commands cold.
ssh ubuntu@203.0.113.10
Connect to a remote server. Replace ubuntu with your username and the IP with your instance's public IP.
ssh -i ~/.ssh/mykey.pem ubuntu@203.0.113.10
Connect using a specific private key file — required for AWS EC2 instances and others that use key-pair authentication.
ssh-keygen -t ed25519 -C "your_email@example.com"
Generate a new SSH key pair. ed25519 is the modern, recommended algorithm. Your public key goes on the server; your private key stays on your machine.
cat ~/.ssh/id_ed25519.pub
View your public key so you can copy it to a server's authorized_keys or paste it into a cloud provider's console.
ssh-copy-id ubuntu@203.0.113.10
Copies your public key to a remote server's authorized keys automatically. Much easier than doing it manually.
scp file.txt ubuntu@203.0.113.10:/home/ubuntu/
Securely copy a file to a remote server over SSH. Use scp -r for directories.
ssh -L 8080:localhost:80 ubuntu@203.0.113.10
SSH tunneling / port forwarding. Forwards your local port 8080 to port 80 on the remote server. Incredibly useful for accessing services that aren't publicly exposed (databases, internal dashboards).
10. Package Management (apt)
For Debian/Ubuntu-based systems — the most common Linux distros you'll encounter on AWS, GCP, and Azure.
sudo apt-get update
Refreshes the package list from repositories. Always run this before installing anything. It doesn't install or upgrade anything — it just updates the metadata.
sudo apt-get upgrade
Upgrades all installed packages to their latest versions. Run update first.
sudo apt-get install nginx
Installs a package by name. You'll use this constantly when provisioning new servers.
sudo apt-get remove nginx
Removes a package but leaves its config files in place.
sudo apt-get purge nginx
Removes a package and its config files. Use this for a clean uninstall.
sudo apt-get autoremove
Removes packages that were installed as dependencies but are no longer needed. Good for keeping VMs lean.
apt-cache search keyword
Search available packages by keyword without installing anything.
11. System Monitoring & Disk
df -h
Shows disk usage of all mounted filesystems in human-readable format (GB, MB). The first thing to check when you get a "disk full" alert.
du -sh /var/log/
Shows the total size of a specific directory. Use du -sh * inside a directory to see sizes of all subdirectories at once.
free -h
Shows memory usage (total, used, free, cached) in human-readable format.
uptime
Shows how long the system has been running and the load average over 1, 5, and 15 minutes. A quick health check.
uname -a
Prints system information: kernel version, architecture, OS. Useful when you're not sure exactly what you're running on.
lsblk
Lists all block devices (disks and partitions). Use this after attaching a new EBS volume (AWS) or persistent disk (GCP) to see it appear.
mount /dev/sdb1 /mnt/data
Mounts a disk partition to a directory. You'll do this after attaching and formatting new cloud storage volumes.
12. Text Processing & Editing
echo "Hello, World!"
Prints text to the terminal. Use with redirection to write to files: echo "export PATH=$PATH:/usr/local/bin" >> ~/.bashrc
nano filename.txt
A simple, beginner-friendly text editor. Use Ctrl+O to save, Ctrl+X to exit. Good for quick edits on remote servers.
vim filename.txt
A powerful but steep-learning-curve editor. i to enter insert mode, Esc then :wq to save and quit. Worth learning the basics.
sed -i 's/old-value/new-value/g' config.txt
Stream editor — find and replace text in a file without opening an editor. The -i flag edits in-place. Extremely useful in deployment scripts.
awk '{print $1, $3}' data.txt
A powerful text-processing tool. This example prints the 1st and 3rd columns. Great for parsing log files and extracting specific fields.
wc -l filename.txt
Word count — counts lines, words, or characters. wc -l counts lines. Use it to count log entries: grep "ERROR" app.log | wc -l
sort filename.txt
Sorts lines alphabetically. Use sort -n for numerical sort, sort -r for reverse.
uniq -c sorted.txt
Counts duplicate adjacent lines — always pair with sort first. Classic pattern for frequency analysis.
cut -d',' -f1,3 data.csv
Extracts specific columns from delimited files. Perfect for parsing CSV exports from cloud billing or logs.
13. Environment & Shell
env
Lists all environment variables currently set. Use this to verify that your secrets and config values loaded correctly.
export MY_VAR="hello"
Sets an environment variable for the current session and any child processes. Use this for passing config to scripts.
echo $MY_VAR
Prints the value of an environment variable.
source ~/.bashrc
Reloads your shell config file. Run this after editing .bashrc or .bash_profile so changes take effect without logging out.
history
Shows your command history. Use history | grep ssh to find a previously used SSH command.
!42
Re-runs command number 42 from your history. Use !! to repeat the last command (common pattern: sudo !! to re-run the last command with sudo).
alias ll='ls -la'
Creates a shortcut for a command. Add your aliases to ~/.bashrc to make them permanent.
crontab -e
Opens the cron job editor to schedule recurring tasks. This is how you automate backups, cleanup scripts, and health checks on cloud VMs.
shutdown -h +10
Shuts down the system in 10 minutes. Use shutdown -r now to reboot immediately. Always requires root/sudo.
Cloud Provider Quick Reference
All major cloud providers offer a browser-based Cloud Shell that drops you straight into a bash environment — no SSH setup required.
| Provider | Cloud Shell Access | CLI Tool |
|---|---|---|
| AWS | CloudShell in Console |
aws CLI |
| Google Cloud | Cloud Shell button (top nav) |
gcloud CLI |
| Azure | Cloud Shell icon (top nav) |
az CLI (bash or PowerShell) |
| Oracle Cloud | Cloud Shell in Console |
oci CLI |
| IBM Cloud | Cloud Shell button |
ibmcloud CLI |
Handy Cloud CLI Examples
AWS — List all S3 buckets:
aws s3 ls
AWS — Copy a file to S3:
aws s3 cp myfile.txt s3://my-bucket/
GCP — List Compute Engine instances:
gcloud compute instances list
GCP — SSH into an instance:
gcloud compute ssh my-instance --zone=us-central1-a
Azure — List resource groups:
az group list --output table
Azure — Show VM status:
az vm show -g MyResourceGroup -n MyVM --show-details
Putting It All Together: A Real Workflow
Here's what a typical cloud debugging session might look like using the commands above:
# 1. SSH into your instance
ssh -i ~/.ssh/prod-key.pem ubuntu@203.0.113.10
# 2. Check who you are and system status
whoami
uptime
free -h
df -h
# 3. Find what's eating disk space
du -sh /var/log/*
# 4. Check if your app process is running
ps aux | grep myapp
# 5. Watch live logs
tail -f /var/log/myapp/app.log
# 6. Count errors in the last hour's log
grep "ERROR" /var/log/myapp/app.log | wc -l
# 7. Check which ports are listening
ss -tuln
# 8. Restart a service if needed
sudo systemctl restart myapp
Final Thoughts
The CLI felt intimidating to me at first too. Now I reach for it before the console almost every time it's faster, scriptable, and forces you to actually understand what's happening on your infrastructure rather than clicking through abstractions.
Start with the navigation and file commands until they're muscle memory. Then move to grep, pipes, and permissions. Once those click, the rest follows naturally.
The best way to get comfortable? Stop avoiding the CLI and use it for everything even when the GUI would be faster at first. The short-term friction pays off fast.
If there are specific command categories you'd like me to expand on, drop a comment below.


Top comments (0)