An alias is a shortcut: a short name that expands to a longer command. If you type the same long commands every day, such as checking logs, restarting services or listing files a certain way, aliases save a lot of keystrokes.
Create an alias
alias ll='ls -lAh'
ll /var/www
The syntax is alias name='command', with no spaces around =. Use single quotes so variables inside are expanded when the alias runs, not when it’s defined.
List and remove aliases:
alias # show all aliases
alias ll # show one
unalias ll # remove it
Make aliases permanent
Aliases defined at the prompt disappear when you log out. Put them in ~/.bashrc:
nano ~/.bashrc
# add your aliases at the end, then:
source ~/.bashrc
Ubuntu’s default ~/.bashrc also loads ~/.bash_aliases if it exists. Keeping aliases in that separate file is tidy:
echo "alias ll='ls -lAh'" >> ~/.bash_aliases
source ~/.bashrc
For all users, put them in /etc/profile.d/aliases.sh (login shells) or /etc/bash.bashrc (interactive shells on Debian and Ubuntu).
On zsh, use ~/.zshrc. The syntax is the same.
Useful aliases for servers
# listing
alias ll='ls -lAh'
alias lt='ls -lAhtr'
# safety nets for interactive use
alias rm='rm -I'
alias cp='cp -i'
alias mv='mv -i'
# disk and memory
alias df='df -hT -x tmpfs -x devtmpfs'
alias du1='du -h --max-depth=1 | sort -h'
alias mem='free -h'
# processes and ports
alias psg='ps aux | grep -v grep | grep -i'
alias ports='ss -tulpn'
# services and logs
alias sc='sudo systemctl'
alias jf='journalctl -f -u'
alias nginxt='sudo nginx -t && sudo systemctl reload nginx'
# networking
alias myip='curl -s https://ifconfig.me; echo'
# Docker
alias dps='docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"'
alias dcu='docker compose up -d'
alias dcl='docker compose logs -f --tail=100'
# navigation
alias ..='cd ..'
alias ...='cd ../..'
alias www='cd /var/www'
Use them like psg nginx, jf myapp and sc restart php8.3-fpm. Arguments are appended at the end of the alias.
Aliases can’t take arguments in the middle: use functions
An alias only does text replacement at the start of the command. For arguments in other positions, logic or several commands, write a shell function. It goes in the same ~/.bashrc:
mkcd() { mkdir -p -- "$1" && cd -- "$1"; }
# tail an Nginx site's error log
nerr() { sudo tail -F "/var/log/nginx/${1:-error}.log"; }
# quick backup of a file before editing
bak() { cp -a -- "$1" "$1.$(date +%Y%m%d-%H%M%S).bak"; }
# check a site's certificate expiry
certexp() { echo | openssl s_client -servername "$1" -connect "$1:443" 2>/dev/null | openssl x509 -noout -enddate; }
See Bash functions.
Bypass an alias
If rm is aliased to rm -I and you want the plain command:
\rm file # backslash skips the alias
command rm file
/bin/rm file
type rm tells you whether a name is an alias, function, builtin or file.
Aliases and sudo
sudo ll fails, because sudo doesn’t see your aliases. A trick: define
alias sudo='sudo '
The trailing space makes Bash check the next word for aliases too, so sudo ll works.
Aliases in scripts
Aliases aren’t expanded in non-interactive scripts by default, and scripts shouldn’t depend on your personal aliases anyway. Use full commands or functions in scripts. This also explains why something that works in your terminal can behave differently in cron or a script.
Don’t shadow with surprises
Redefining standard commands (alias ls='ls --color=auto') is common and harmless. Aliases that change behaviour drastically can surprise you on another server, where they don’t exist. rm -I is a good example: you get used to the prompt. Habits like checking with ls before rm travel better. See rm safely.
Quick reference
| Task | Command |
|---|---|
| Create | alias name='cmd' |
| List | alias |
| Remove | unalias name |
| Permanent | add to ~/.bashrc or ~/.bash_aliases |
| Reload | source ~/.bashrc |
| Bypass | \name or command name |
| What is it? | type name |