The terminal is where developers live. A few minutes learning shortcuts and tools saves hours over a career. These are the techniques that make the biggest difference.
Shell Basics That Pay Off#
History Navigation#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # Search history with Ctrl+R
# Type partial command, press Ctrl+R repeatedly to cycle
# Run last command
!!
# Run last command with sudo
sudo !!
# Run last command starting with 'git'
!git
# Replace text in last command
^typo^fixed
# If last command was: git psuh
# ^psuh^push runs: git push
# Last argument of previous command
cd /very/long/path/to/directory
ls $_ # $_ = /very/long/path/to/directory
|
Keyboard Shortcuts#
1
2
3
4
5
6
7
8
| Ctrl+A # Move to beginning of line
Ctrl+E # Move to end of line
Ctrl+U # Delete from cursor to beginning
Ctrl+K # Delete from cursor to end
Ctrl+W # Delete word before cursor
Alt+B # Move back one word
Alt+F # Move forward one word
Ctrl+L # Clear screen (keeps current line)
|
Brace Expansion#
1
2
3
4
5
6
7
8
9
10
11
| # Create multiple directories
mkdir -p project/{src,tests,docs}
# Create multiple files
touch file{1,2,3}.txt
# Backup a file
cp config.yml{,.bak} # Creates config.yml.bak
# Rename with pattern
mv file.{txt,md} # Renames file.txt to file.md
|
fzf - Fuzzy Finder#
1
2
3
4
5
6
7
8
9
10
11
12
13
| # Install
brew install fzf # macOS
apt install fzf # Debian/Ubuntu
# Search files
fzf
# Pipe anything to fzf
cat file.txt | fzf
ps aux | fzf
# Ctrl+R replacement (add to .bashrc/.zshrc)
# Much better history search
|
ripgrep (rg) - Fast Search#
1
2
3
4
5
6
7
8
9
10
11
12
13
| # Install
brew install ripgrep
# Search in files (faster than grep)
rg "pattern"
rg "TODO" --type py
rg "function" -g "*.js"
# Case insensitive
rg -i "error"
# Show context
rg -C 3 "exception" # 3 lines before and after
|
fd - Better Find#
1
2
3
4
5
6
7
8
9
10
| # Install
brew install fd
# Find files
fd "pattern"
fd -e py # Find .py files
fd -t d # Find directories only
# Execute on results
fd -e log -x rm # Delete all .log files
|
bat - Better Cat#
1
2
3
4
5
6
7
8
| # Install
brew install bat
# Syntax highlighting, line numbers, git changes
bat file.py
# Use as man pager
export MANPAGER="sh -c 'col -bx | bat -l man -p'"
|
eza/exa - Better ls#
1
2
3
4
5
6
7
8
| # Install
brew install eza
# Tree view with git status
eza --tree --level=2 --git
# Long format with icons
eza -la --icons
|
jq - JSON Processing#
1
2
3
4
5
6
7
8
9
10
11
| # Pretty print JSON
cat data.json | jq .
# Extract field
curl api.example.com/users | jq '.[0].name'
# Filter array
jq '.[] | select(.active == true)'
# Transform
jq '{name: .user.name, email: .user.email}'
|
Tmux Essentials#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| # Start new session
tmux new -s project
# Detach: Ctrl+B, then D
# List sessions
tmux ls
# Attach to session
tmux attach -t project
# Split panes
Ctrl+B % # Vertical split
Ctrl+B " # Horizontal split
Ctrl+B o # Switch pane
Ctrl+B z # Zoom pane (toggle)
# Windows
Ctrl+B c # New window
Ctrl+B n # Next window
Ctrl+B p # Previous window
Ctrl+B , # Rename window
|
Git Shortcuts#
1
2
3
4
5
6
7
8
9
10
11
| # .gitconfig
[alias]
s = status -sb
co = checkout
br = branch
ci = commit
ca = commit --amend
lg = log --oneline --graph --decorate -20
unstage = reset HEAD --
last = log -1 HEAD
aliases = config --get-regexp alias
|
1
2
3
4
5
6
| # Common workflows
git s # Short status
git lg # Pretty log
git co - # Switch to previous branch
git stash -u # Stash including untracked
git stash pop # Apply and remove stash
|
Shell Aliases#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| # Add to .bashrc or .zshrc
# Navigation
alias ..="cd .."
alias ...="cd ../.."
alias ~="cd ~"
# Safety
alias rm="rm -i"
alias mv="mv -i"
alias cp="cp -i"
# Shortcuts
alias ll="ls -lah"
alias la="ls -la"
alias g="git"
alias k="kubectl"
alias d="docker"
alias dc="docker compose"
# Quick edits
alias zshrc="$EDITOR ~/.zshrc"
alias reload="source ~/.zshrc"
# Common tasks
alias ports="netstat -tulanp"
alias myip="curl ifconfig.me"
alias weather="curl wttr.in"
|
Functions#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| # Make directory and cd into it
mkcd() {
mkdir -p "$1" && cd "$1"
}
# Extract any archive
extract() {
case $1 in
*.tar.gz) tar xzf "$1" ;;
*.tar.bz2) tar xjf "$1" ;;
*.tar.xz) tar xJf "$1" ;;
*.zip) unzip "$1" ;;
*.gz) gunzip "$1" ;;
*) echo "Unknown format: $1" ;;
esac
}
# Find and kill process by name
killnamed() {
ps aux | grep "$1" | grep -v grep | awk '{print $2}' | xargs kill -9
}
# Quick HTTP server
serve() {
python3 -m http.server ${1:-8000}
}
# Git clone and cd
gclone() {
git clone "$1" && cd "$(basename "$1" .git)"
}
|
Quick One-Liners#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| # Find large files
find . -type f -size +100M
# Disk usage by directory
du -sh */ | sort -h
# Watch command output
watch -n 2 'kubectl get pods'
# Run command on file change
while inotifywait -e modify file.py; do python file.py; done
# Parallel execution
cat urls.txt | xargs -P 10 -I {} curl -s {}
# Quick calculations
echo $((2**10)) # 1024
python3 -c "print(2**100)"
# Generate password
openssl rand -base64 32
# Quick timestamp
date +%Y%m%d_%H%M%S
|
Environment Management#
1
2
3
4
5
6
| # .envrc with direnv
# Auto-load environment per directory
echo 'export API_KEY=xxx' > .envrc
direnv allow
# Now API_KEY is set when you cd into this directory
|
SSH Config#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # ~/.ssh/config
Host dev
HostName dev.example.com
User deploy
IdentityFile ~/.ssh/dev_key
Host prod
HostName prod.example.com
User deploy
ProxyJump bastion
Host *
AddKeysToAgent yes
IdentitiesOnly yes
# Now just: ssh dev
|
Prompt Customization#
1
2
3
4
5
| # Starship - cross-shell prompt
brew install starship
echo 'eval "$(starship init zsh)"' >> ~/.zshrc
# Shows git status, language versions, errors, duration
|
The Power Combo#
My essential setup:
1
2
3
4
5
6
7
8
9
10
11
12
| # Install essentials
brew install fzf ripgrep fd bat eza jq starship tmux
# Configure fzf
echo 'eval "$(fzf --zsh)"' >> ~/.zshrc
# Better defaults
export FZF_DEFAULT_COMMAND='fd --type f'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
# Use bat for previews
export FZF_CTRL_T_OPTS="--preview 'bat --color=always {}'"
|
Terminal productivity compounds. Each shortcut saves seconds, but those seconds add up across thousands of commands. Invest an hour learning these tools, save days over your career.
Start with history search (Ctrl+R) and fzf. Add ripgrep for searching code. Build aliases for commands you type daily. The terminal that’s customized to your workflow becomes an extension of your thinking.
📬 Get the Newsletter
Weekly insights on DevOps, automation, and CLI mastery. No spam, unsubscribe anytime.