I keep coming back to this story: in 1986, Jon Bentley asked Donald Knuth to demonstrate literate programming by writing a program to count word frequencies. Knuth wrote an elegant 10+ page solution. Doug McIlroy, asked to review Knuth’s work, offered an interesting counterpoint in just 6 lines of shell:
tr -cs A-Za-z '\n' | tr A-Z a-z | sort | uniq -c | sort -rn | sed ${1}qWorth mentioning: this wasn’t a competition or a criticism. Knuth is one of the greatest programmers alive. He was demonstrating how to write complete programs from scratch. McIlroy was showing what happens when you compose small tools that already exist.
Once the Unix philosophy clicks, you start seeing these shortcuts everywhere. Here are the ones I actually use.
History
!! repeats the last command. sudo !! is your friend when you forget sudo.
!$ gets the last argument. Create a directory and cd into it:
mkdir /tmp/new
cd !$^foo^bar runs the previous command replacing foo with bar. Great for typos.
Ctrl + r searches history. But if you install fzf, it replaces the default search with a fuzzy finder. Game changer. seriously, install fzf
Prevent accidents
I’ve lost files to careless rm and mv. Now I use these aliases:
alias cp='cp -i'
alias mv='mv -i'
alias rm='rm -i'The -i flag asks before overwriting or deleting.
Readline shortcuts
Navigation:
Ctrl + abeginning of lineCtrl + eend of lineAlt + bback one wordAlt + fforward one word
Editing:
Ctrl + wdelete word backwardCtrl + udelete to beginning of lineCtrl + kdelete to end of lineCtrl + ypaste what you deleted
Search:
Ctrl + rsearch history backwardCtrl + gcancel search
Directory tricks
cd - returns to the previous directory.
mkdir -p creates nested directories:
mkdir -p project/{src,tests,docs}For jumping to frequently used directories, zoxide learns your habits. After visiting a directory once, z project takes you there from anywhere.
Brace expansion
Copy a file with a new extension without typing the name twice:
cp config.json{,.backup}Rsync
Once you use rsync, you never go back to scp. It only transfers what changed:
rsync -avz ./local/ user@server:/remote/Quick commands
Pretty print JSON:
jq . file.jsonIf you don’t have jq installed: python3 -m json.tool file.json
Get your external IP:
curl ifconfig.meServe current directory over HTTP:
python3 -m http.server 8000Empty a file:
> file.logJob control
You started a long download and forgot to use nohup. Now you need to leave. Don’t cancel it:
Ctrl + z # pause
bg # resume in background
disown %1 # detach from sessionNow you can close the terminal and the job keeps running.
macOS specific
Copy command output to clipboard:
cat file.txt | pbcopyPaste from clipboard:
pbpaste > file.txtOpen files or URLs with default app:
open file.pdf
open https://example.com
open . # opens current folder in FinderPrevent sleep during a long task:
caffeinate -i long_running_script.shQuick Look from terminal:
qlmanage -p file.pdf 2>/dev/nullFlush DNS cache:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder