The shell keeps a pocket dictionary of words you hand it — write the entries yourself.
You've typed `ls -lh --color=auto` a thousand times. One line in your dotfiles and you'll never type it again.
alias maps a short name to a longer command. Type `alias g="git status --short"` and from then on `g` expands to that whole string the moment it hits the shell. It's pure text substitution — the shell swaps the alias word for its expansion and re-parses, which is why aliases are dead simple and why they break in sneaky places (like non-interactive scripts).
Real systems are full of repeated incantations you don't want to retype and re-verify: `docker compose logs --tail=300 -f`, `ssh -o ServerAliveInterval=30 deploy@prod`, `git log --oneline --graph --all`. Baking those into aliases is how you stop copy-pasting muscle-memory typos and start shipping a `ll` that always means 'listing with details and color'. Put them in ~/.bashrc or ~/.zshrc and every new login loads them.
$ alias ll="ls -la" $ ll
total 24 drwxr-xr-x 3 kmail kmail 4096 Sep 19 09:12 . drwxr-xr-x 11 kmail kmail 4096 Sep 19 08:55 .. -rw-r--r-- 1 kmail kmail 102 Sep 19 09:12 app.conf -rw-r--r-- 1 kmail kmail 56 Sep 19 09:12 notes.md drwxr-xr-x 2 kmail kmail 4096 Sep 19 09:13 src
The classic. `ls -la` with color, details and hidden files bound to two characters — verified output from an actual directory.
$ alias logs="journalctl -u nginx --since today --no-pager" $ logs | tail -3
Sep 19 09:14:02 srv nginx[1282]: 10.0.0.7 - - [19/Sep/2026:09:14:02] "GET /tutorials HTTP/1.1" 200 1582 "-" "Mozilla/5.0" Sep 19 09:14:05 srv nginx[1282]: 10.0.0.7 - - [19/Sep/2026:09:14:05] "GET /health HTTP/1.1" 200 18 "-" "curl/8.5.0" Sep 19 09:14:11 srv nginx[1282]: 10.0.0.7 - - [19/Sep/2026:09:14:11] "GET /tutorials/gzip HTTP/1.1" 200 3184 "-" "Mozilla/5.0"
Aliases shine for multi-flag diagnostic commands you run during every incident you triage. One word now means 'today's nginx journal, unbounded'.
$ alias cp="cp -i" $ cp app.conf app.conf.bak cp: overwrite 'app.conf.bak'? n
cp: overwrite 'app.conf.bak'? n
A safety alias: `-i` makes cp ask before clobbering an existing file. This is exactly why the default Ubuntu interactive profile ships `alias cp='cp -i'` — confirmed on this box, cp resolves to /usr/bin/cp with the alias attached interactively.
$ type ll aliased to `ls --color=auto -la' $ unalias ll $ type ll -bash: type: ll: not found
type ll aliased to `ls --color=auto -la' unalias ll type ll -bash: type: ll: not found
`type` tells you whether a word is an alias, a builtin or a real binary — use it before you assume. `unalias` drops the shortcut for this shell session only; your next login it's back.
| Flag | Meaning |
|---|---|
alias name=command | Define a shortcut in the current shell. Quote anything with spaces so it's stored as one string. |
alias (no args) | Print every alias currently defined — great for auditing what your interactive shell actually loaded. |
alias -p | Bash-only: print aliases in a re-readable form (`alias ll='ls -la'`) suitable for writing back to config. |
unalias name | Remove an alias; the original command is reachable again with its real name, or `\aliasname`. |
unalias -a | Remove all aliases at once — a blunt reset for scripting or a misconfigured profile. |
\name | Prefix the shortcut with a backslash to bypass the alias for one use and run the underlying command. |
The alias command dates to the original Bourne shell (sh) written by Stephen Bourne at Bell Labs, alongside the famous `type` builtin. C shell added `~/.cshrc`-style aliasing and made the feature famous; POSIX later standardized it as a required shell utility. Even today the two-letter word is reserved shell syntax in every POSIX shell.
Bash gained `shopt expand_aliases` in the 1990s, and that switch is why aliases silently do nothing in scripts by default: non-interactive shells keep expansion off unless you enable it. It's a deliberate safety decision — scripts get the real binaries, not whatever shortcuts your interactive profile installed — but it still catches everyone.