Every developer needs Linux skills. Even if youβre on macOS or Windows, your code runs on Linux servers, Docker containers, and CI/CD pipelines. This guide covers the commands and concepts youβll use daily, from basic navigation to system administration.
For quick reference, keep the Linux terminal cheat sheet open.
Navigating the File System
pwd # print current directory
ls # list files
ls -la # list all files with details
cd /var/log # change directory
cd ~ # go to home directory
cd - # go to previous directory
# Find files
find . -name "*.log" # by name
find . -type f -mtime -7 # modified in last 7 days
find . -size +100M # larger than 100MB
File System Structure
/ # root
βββ home/ # user home directories
βββ etc/ # configuration files
βββ var/ # variable data (logs, databases)
βββ tmp/ # temporary files
βββ usr/ # user programs and libraries
βββ opt/ # optional/third-party software
βββ bin/ # essential binaries
βββ proc/ # virtual filesystem (process info)
Working with Files
# Create
touch file.txt # create empty file
mkdir -p path/to/dir # create nested directories
# Copy, move, delete
cp file.txt backup.txt # copy
cp -r dir/ backup/ # copy directory recursively
mv old.txt new.txt # move/rename
rm file.txt # delete file
rm -rf directory/ # delete directory (careful!)
# View contents
cat file.txt # print entire file
less file.txt # paginated viewer (q to quit)
head -20 file.txt # first 20 lines
tail -20 file.txt # last 20 lines
tail -f /var/log/syslog # follow log in real-time
# Edit
nano file.txt # simple editor
vim file.txt # powerful editor (steep learning curve)
Text Processing
These commands are the backbone of shell scripting:
# Search
grep "error" logfile.txt # find lines containing "error"
grep -r "TODO" src/ # recursive search
grep -i "warning" log.txt # case-insensitive
grep -c "error" log.txt # count matches
# Transform
sed 's/old/new/g' file.txt # find and replace
sed -i 's/old/new/g' file.txt # in-place edit
awk '{print $1, $3}' data.txt # print columns 1 and 3
sort file.txt # sort lines
sort -u file.txt # sort and deduplicate
uniq -c # count consecutive duplicates
wc -l file.txt # count lines
# Combine with pipes
cat access.log | grep "500" | awk '{print $1}' | sort | uniq -c | sort -rn | head -10
# β top 10 IPs causing 500 errors
Permissions
Every file has an owner, a group, and permission bits:
ls -la
# -rw-r--r-- 1 alice devs 4096 Mar 15 10:00 file.txt
# ββββ€βββ€βββ€
# β β β βββ others: read only
# β β ββββββ group: read only
# β ββββββββββ owner: read + write
# βββββββββββββ file type (- = file, d = directory)
# Change permissions
chmod 755 script.sh # rwxr-xr-x (owner: all, others: read+execute)
chmod +x script.sh # add execute permission
chmod -R 644 public/ # recursive
# Change ownership
chown alice:devs file.txt # change owner and group
chown -R www-data:www-data /var/www/ # recursive
Common permission patterns:
644β files (owner read/write, others read)755β directories and scripts (owner all, others read/execute)600β private files like SSH keys (owner read/write only)
If youβre getting βPermission denied,β see our permission denied fix.
Process Management
# View processes
ps aux # all processes
ps aux | grep node # find specific process
top # interactive process viewer
htop # better interactive viewer
# Background/foreground
long-command & # run in background
jobs # list background jobs
fg %1 # bring job 1 to foreground
Ctrl+Z # suspend current process
bg %1 # resume in background
# Kill processes
kill 12345 # graceful shutdown (SIGTERM)
kill -9 12345 # force kill (SIGKILL)
killall node # kill all processes by name
pkill -f "node server.js" # kill by command pattern
Disk and Memory
# Disk usage
df -h # filesystem disk usage
du -sh * # size of each item in current dir
du -sh /var/log # size of a specific directory
ncdu / # interactive disk usage viewer
# Memory
free -h # memory usage
If youβre running out of disk space, see our disk space full fix. For βtoo many open files,β see the open files fix.
Networking
# Check connectivity
ping google.com
curl -I https://example.com # HTTP headers only
curl -s https://api.example.com # silent request
wget https://example.com/file # download file
# Ports and connections
ss -tlnp # listening ports (modern)
netstat -tlnp # listening ports (legacy)
lsof -i :3000 # what's using port 3000
# DNS
dig example.com # DNS lookup
nslookup example.com # simpler DNS lookup
host example.com # simplest DNS lookup
# Transfer files
scp file.txt user@server:/path/ # copy to remote
rsync -avz src/ user@server:dst/ # sync directories
SSH
# Connect
ssh user@server.com
ssh -p 2222 user@server.com # custom port
ssh -i ~/.ssh/mykey user@server # specific key
# SSH config (saves typing)
# ~/.ssh/config
Host myserver
HostName 192.168.1.100
User alice
Port 2222
IdentityFile ~/.ssh/mykey
# Now just:
ssh myserver
# Generate SSH key
ssh-keygen -t ed25519 -C "alice@example.com"
ssh-copy-id user@server # copy public key to server
Package Management
# Debian/Ubuntu (apt)
sudo apt update # refresh package list
sudo apt install nginx # install
sudo apt remove nginx # remove
sudo apt upgrade # upgrade all packages
sudo apt autoremove # clean up unused packages
# Fedora/RHEL (dnf)
sudo dnf install nginx
sudo dnf remove nginx
sudo dnf upgrade
# Arch (pacman)
sudo pacman -S nginx
sudo pacman -R nginx
sudo pacman -Syu # full system upgrade
If a command isnβt found after installing, see our command not found fix.
Shell Scripting Basics
#!/bin/bash
set -euo pipefail # exit on error, undefined vars, pipe failures
# Variables
NAME="World"
echo "Hello, $NAME"
# Conditionals
if [ -f "config.json" ]; then
echo "Config exists"
elif [ -d "config/" ]; then
echo "Config directory exists"
else
echo "No config found"
fi
# Loops
for file in *.log; do
echo "Processing $file"
gzip "$file"
done
# Functions
deploy() {
local env="${1:?Usage: deploy <environment>}"
echo "Deploying to $env..."
rsync -avz dist/ "server:/var/www/$env/"
}
deploy production
Always start scripts with set -euo pipefail β it catches errors that would otherwise silently pass.
Systemd Services
Manage background services:
# Control services
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl status nginx
sudo systemctl enable nginx # start on boot
sudo systemctl disable nginx # don't start on boot
# View logs
journalctl -u nginx # logs for a service
journalctl -u nginx -f # follow logs
journalctl --since "1 hour ago" # recent logs
Environment Variables
# Set for current session
export DATABASE_URL="postgres://localhost/mydb"
# Set permanently
echo 'export DATABASE_URL="postgres://localhost/mydb"' >> ~/.bashrc
source ~/.bashrc
# View
echo $DATABASE_URL
env # all environment variables
env | grep DATABASE # search
# Use in commands
psql "$DATABASE_URL"
Cron Jobs
Schedule recurring tasks:
# Edit crontab
crontab -e
# Format: minute hour day month weekday command
# ββββββ minute (0-59)
# β ββββββ hour (0-23)
# β β ββββββ day of month (1-31)
# β β β ββββββ month (1-12)
# β β β β ββββββ day of week (0-7, 0 and 7 = Sunday)
# β β β β β
0 2 * * * /home/alice/backup.sh # daily at 2am
*/5 * * * * curl -s https://mysite.com/health # every 5 minutes
0 0 * * 0 apt update && apt upgrade -y # weekly on Sunday midnight
# List current cron jobs
crontab -l
# View cron logs
grep CRON /var/log/syslog
tmux β Terminal Multiplexer
Keep sessions alive after disconnecting:
# Start a new session
tmux new -s myproject
# Detach (session keeps running)
Ctrl+B, then D
# Reattach
tmux attach -t myproject
# List sessions
tmux ls
# Split panes
Ctrl+B, % # vertical split
Ctrl+B, " # horizontal split
Ctrl+B, arrow keys # navigate panes
tmux is essential for remote servers β your processes keep running even if your SSH connection drops.
Useful One-Liners
# Find and replace in multiple files
find . -name "*.js" -exec sed -i 's/old/new/g' {} +
# Watch a command repeatedly
watch -n 2 'df -h' # run df -h every 2 seconds
# Create a quick HTTP server
python3 -m http.server 8000
# Compress/extract
tar -czf archive.tar.gz dir/ # compress
tar -xzf archive.tar.gz # extract
# Check which process is using a port
lsof -i :3000 | grep LISTEN
Troubleshooting
Common Linux errors with detailed fixes:
- Command not found β binary not in PATH
- Permission denied β wrong file permissions or ownership
- Disk space full β find and clean up large files
- Too many open files β ulimit too low
Next Steps
- Bookmark the Linux terminal cheat sheet for daily reference
- Learn Docker to containerize your applications
- Set up Nginx as a web server or reverse proxy
- Deploy to Kubernetes for orchestration
- Manage infrastructure with Git version control