We learn ls, cd, and grep — and then stop. The shell authors solved most of our frustrations back in 1989. Here's what they built. Split into universal POSIX tricks and Bash/Zsh extras.
Universal · Works on almost any POSIX shell
Instantly wipes the last word. Beats holding Backspace when you mistype a long path segment.
/var/log/nginx/ → Ctrl+W → /var/log/
Ctrl+U cuts from cursor to line start. Ctrl+K cuts to end. Ctrl+Y yanks it back. Perfect for stashing a long command while you run a quick check.
rsync -avz /src user@host:/dest # Ctrl+U to cut
ls /dest # quick check
# Ctrl+Y to paste the rsync back
Skip the Home/End keys — these are right on the home row and much faster.
Jump backward/forward one whole word at a time instead of one character.
sudo systemctl restart nginx
# ^ Alt+B moves cursor here each press
Mac users: enable "Use Option as Meta key" in your terminal settings.
Unlike typing clear, this works mid-command. Wipes the clutter, keeps your cursor and current input intact.
Accidentally cat-ed a binary? Your terminal is showing ancient runes. Type reset blind and hit Enter — it heals itself.
cat /usr/bin/ls # oops — garbled output everywhere
reset # type this even if invisible, then Enter
Ctrl+C cancels the current command. Ctrl+D sends EOF — closes input streams, or logs you out if the prompt is empty (be careful).
Directory Navigation
Instantly jump back where you were. Run it again to return. Like a TV channel flipper for directories.
cd /usr/local/etc/postfix
cd /var/log
cd - # back to /usr/local/etc/postfix
cd - # back to /var/log
Like cd - but for multiple locations. pushd saves current dir and jumps to new one. popd returns you in reverse order.
pushd /etc # save current, jump to /etc
pushd /var/log # save again, jump to /var/log
popd # back to /etc
popd # back to original dir
Empties the file while preserving permissions, ownership, and open file handles. Much cleaner than rm + touch for log rotation.
> /var/log/app.log # truncates instantly
# processes with the file open won't break
Expands to the last argument of the previous command. Perfect for mkdir + cd in one shot.
mkdir -p /opt/myapp/config && cd "$_"
# no retyping the path
Scripting Safety Flags
set -e exits on error. set -u errors on unset variables — prevents disasters like rm -rf /usr/${TYPO}/*. pipefail catches failures inside pipes.
#!/bin/bash
set -euo pipefail # put this at the top of every script
Learn the edge cases of set -e before relying on it inside conditionals and loops.
Bash & Zsh · Interactive Shell Extras
Press, then type any keyword from a past command. Finds it instantly. Press again to cycle further back through matches.
Ctrl+R → type "rsync" → finds last rsync command you ran
# press Ctrl+R again to go further back
The classic "I forgot sudo" fix. Expands to your entire previous command.
systemctl restart nginx # Permission denied
sudo !! # runs: sudo systemctl restart nginx
Alt+. inserts it live at cursor (you can edit before running). Press repeatedly to cycle back through history. !$ expands blindly at Enter.
vim /etc/nginx/nginx.conf
# press Alt+. on next command → inserts: /etc/nginx/nginx.conf
cat Alt+. → cat /etc/nginx/nginx.conf
One-liner grown into a four-pipe monster? Open it in Vim/Nano, edit comfortably, save and exit — shell runs it immediately.
Opens previous command in $EDITOR for clean edits. Works across most shells — more portable than Ctrl+X Ctrl+E.
fc # opens last command in vim to fix and re-run
Expansion Magic
The shell expands brace expressions before running the command. Makes backups, renames, and bulk directory creation one-liners.
cp nginx.conf{,.bak} # → cp nginx.conf nginx.conf.bak
mv report.{txt,md} # → mv report.txt report.md
mkdir -p project/{src,tests,docs} # three dirs at once
Treats command output as a file. Eliminates temp files for operations like diff.
diff <(sort file1.txt) <(sort file2.txt)
# no temp files, no cleanup needed
Enable with shopt -s globstar in Bash (on by default in Zsh). Matches files in all subdirectories — often replaces a find command.
shopt -s globstar
ls **/*.js # all .js files recursively
grep -l "TODO" **/*.py # all Python files with TODO
Process Control & Logging
Forgot to use tmux before starting a long job? Suspend it, background it, then disown it. The process survives even if your SSH connection drops.
Ctrl+Z # suspends the running process
bg # resumes it in background, frees your prompt
disown # detaches from shell — safe to close terminal now
Regular | misses stderr. |& captures both. tee lets you watch live output while saving it simultaneously.
./deploy.sh |& tee deploy.log
# watch in terminal AND save to file at the same time
↑ Back to top
Content based on blog.hofstede.it by Christian Hofstede-Kuhn.
Reformatted for readability.