Guides

alias command in Linux and bash: create, list, remove and keep aliases

The alias command in Linux and bash: define, list and remove aliases, keep them in ~/.bashrc, use a function for arguments, and aliases in scripts.

Published ~7 min read
On this page

Short answer: alias ll='ls -alF' creates a shortcut in the current bash shell: typing ll now runs ls -alF. alias on its own lists every alias, unalias ll removes one. An alias lives only until the shell closes; to keep it, add the same line to ~/.bashrc (or ~/.bash_aliases on Debian and Ubuntu) and run source ~/.bashrc.

bash
alias ll='ls -alF'                        # define
alias                                     # list all
unalias ll                                # remove
echo "alias ll='ls -alF'" >> ~/.bashrc    # keep it for every new shell
source ~/.bashrc                          # load it into this shell too

The outputs on this page come from bash 5.2.15 and dash 0.5.12 on Debian 12, run in a scratch directory on 21 October 2026. The zsh and fish notes follow their manuals; neither shell is installed on that host.

alias cheat sheet

TaskCommand
Define an aliasalias ll='ls -alF'
List all aliasesalias
Show one aliasalias ll
What does a name run?type -a ll
Remove one aliasunalias ll
Remove every alias in this shellunalias -a
Run the real command once\ls
Same, written outcommand ls
Make aliases work after sudoalias sudo='sudo '
Turn aliases on in a bash scriptshopt -s expand_aliases

Define an alias

The form is alias name='value', with no spaces around the equals sign. Quote the value whenever it contains a space, and prefer single quotes so the shell does not expand variables while you define it. bash expands the alias as you type, then adds whatever you typed after it:

bash · Debian 12
$ alias greet='echo hello'
$ greet world
hello world
$ type greet
greet is aliased to `echo hello'

The quoting rule is the one people trip over. Without quotes, bash reads alias ll=ls -l as two separate requests, defines ll as plain ls, and complains about the rest. With spaces around the equals sign, every word becomes a lookup:

bash · Debian 12
$ alias ll=ls -l
bash: alias: -l: not found
$ alias ll = 'ls -l'
bash: alias: ll: not found
bash: alias: =: not found
bash: alias: ls -l: not found

Names can contain dots (alias ..='cd ..' works), but per the bash manual not /, $, a backtick, =, quotes, spaces or characters such as |, &, ; and parentheses: alias 'my alias'=ls fails with invalid alias name. An alias may call another alias: with alias x='echo one' and alias y='x two', typing y prints one two.

List aliases, and check what a name runs

alias (or alias -p) prints every alias in a form you can paste back into a shell, sorted by name. alias name prints one, or bash: alias: name: not found. To see everything a name could mean, including the files on PATH it would otherwise run, use type -a:

bash · Debian 12
$ alias ls='ls --color=auto -F'
$ type -a ls
ls is aliased to `ls --color=auto -F'
ls is /usr/bin/ls
ls is /bin/ls

which does not know about aliases, because it is a separate program that only searches PATH. When a command behaves differently from what its man page says, type -a is the first check; the command not found guide lists the other shadowing cases.

Remove an alias: unalias

bash · Debian 12
$ unalias ll
$ ll
bash: ll: command not found
$ unalias nothere
bash: unalias: nothere: not found
$ unalias -a
$ alias | wc -l
0

unalias only changes the shell you are in. If the alias comes from a startup file, it is back in the next session; grep -n "alias ll" ~/.bashrc ~/.bash_aliases finds the line to delete.

Make an alias permanent

Every new interactive bash that is not a login shell, such as a new terminal tab, reads ~/.bashrc, so an alias written there exists in every terminal you open from then on. Aliases are not passed to child processes the way exported variables are: a fresh bash started without its startup files answered type: ll: not found although the parent had the alias. The startup file is the only way to carry one over.

~/.bash_aliases on Debian and Ubuntu

The default ~/.bashrc that Debian and Ubuntu copy into new home directories (from /etc/skel) contains this block, so you can keep aliases in a file of their own:

/etc/skel/.bashrc · Debian 12
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi
bash
echo "alias ll='ls -alF'" >> ~/.bash_aliases
source ~/.bashrc

Root is the exception on Debian. Debian 12’s default root ~/.bashrc comes from /usr/share/base-files/dot.bashrc, which only has a few commented-out ls and rm -i aliases and does not read ~/.bash_aliases at all. As root, either write the aliases straight into /root/.bashrc or paste the block above into it first. Ubuntu’s skeleton file also defines ll, la and l already; on Debian 12 those lines are commented out.

SSH logins, zsh, fish and every user

  • SSH logins start a login shell, which reads ~/.profile; the stock ~/.profile on Debian and Ubuntu sources ~/.bashrc, so the same aliases appear. If you created a ~/.bash_profile, bash skips ~/.profile; the order is explained in setting environment variables.
  • zsh uses the same alias syntax; put the lines in ~/.zshrc.
  • fish turns alias ll 'ls -alF' into a function, and its manual documents alias --save (or funcsave ll) to keep it.
  • Every user on the machine: Debian and Ubuntu read /etc/bash.bashrc for each interactive bash, so a system-wide alias goes there.

Aliases do not take arguments: use a function

An alias is plain text substitution. It has no $1: whatever you type after it is simply appended at the end. The attempt below printed an empty $1 and then the argument:

bash · Debian 12
$ alias show='echo "[$1]"'
$ show x
[] x

Anything that needs an argument in the middle, or two commands that use it, is a shell function. It goes into ~/.bashrc just like an alias:

~/.bashrc
mkcd() { mkdir -p -- "$1" && cd -- "$1"; }      # make a directory and enter it
logs() { journalctl -u "$1" -n 100 --no-pager; } # last 100 lines of one service

mkcd t1/t2 created both directories and left the shell inside t1/t2. If a function should replace an existing alias of the same name, remove the alias first: an alias wins over a function, and defining ll() { ... } while ll is still an alias fails with syntax error near unexpected token `(', because bash expands ll before it reads the parentheses.

Bypass an alias for one command

All of these ran the real ls while ls was aliased to ls --color=auto -F:

bash
\ls d            # a backslash in front stops alias expansion
command ls d     # skips aliases and functions, runs the builtin or the PATH program
'ls' d           # any quoting of the name works like the backslash
/usr/bin/ls d    # the full path, never an alias

This matters with safety aliases such as alias rm='rm -I', explained in the rm guide: \rm runs without the alias, so check what you type before you reach for it.

Why alias sudo='sudo ' works

bash only expands an alias in the first word of a command. In sudo ll, the first word is sudo, so ll is handed to sudo unexpanded, and sudo, which knows nothing about your shell’s aliases, cannot find a program called ll. The bash manual has the way out: if an alias value ends with a blank, the next word is checked for alias expansion too. The same mechanism with nice, which behaves like sudo here:

bash · Debian 12
$ alias ll='ls -alF'
$ nice ll d
nice: ‘ll’: No such file or directory
$ alias nice='nice '
$ nice ll d
total 8
drwxr-xr-x 2 root root 4096 Oct 21 22:54 ./
drwxr-xr-x 4 root root 4096 Oct 21 22:54 ../
-rw-r--r-- 1 root root    0 Oct 21 22:54 a.txt

alias sudo='sudo ' in ~/.bashrc does the same for sudo. It only expands aliases, which your shell resolves before sudo starts; your functions still do not cross over, because the command sudo runs is a new process.

Aliases in shell scripts

bash does not expand aliases in a non-interactive shell, which is every script. The same three lines failed and worked depending on one option:

bash · Debian 12
$ cat s1.sh
#!/bin/bash
alias ll='ls -alF'
ll d
$ bash s1.sh
s1.sh: line 3: ll: command not found
$ cat s2.sh
#!/bin/bash
shopt -s expand_aliases
alias ll='ls -1'
ll d
$ bash s2.sh
a.txt

Two details from the same test: shopt -s expand_aliases must stand on a line before the alias is used, and an alias defined and used on one line does not take effect on that line, because bash reads the whole line before it runs any of it. That also happens at the prompt: alias ll='ls -lh'; ll still ran the old ll. dash, which is /bin/sh on Debian and Ubuntu, and bash in POSIX mode do expand aliases in scripts, so the same script behaves differently under sh. In practice: write functions in scripts, keep aliases for the prompt. A script that fails with exit status 127 on a name that works at your prompt is often an alias; see exit code 127.

alias errors and what they mean

MessageCauseFix
alias: NAME: not foundNo alias by that name, or spaces around the equals signalias name='value'
alias: -l: not foundValue with a space but no quotesQuote the whole value
invalid alias nameSpace, quote or slash in the namePick a simple name
syntax error near unexpected token `('Defining a function whose name is still an aliasunalias name
NAME: command not found (in a script)Aliases are off in non-interactive bashUse a function
Old behaviour after editing ~/.bashrcThe running shell has not reread the filesource ~/.bashrc

Useful aliases on a server

~/.bash_aliases
alias ll='ls -alF'
alias la='ls -A'
alias ..='cd ..'
alias grep='grep --color=auto'
alias df='df -h -x tmpfs -x devtmpfs'      # sizes in G/M, skip RAM-backed filesystems
alias ports='ss -tulpn'                    # what listens where (run as root for process names)
alias rm='rm -I'                           # one prompt before a big or recursive delete
alias update='sudo apt update && sudo apt upgrade'

On a Linux VPS with root access you can put aliases into /root/.bashrc, into your sudo user’s ~/.bash_aliases, or into /etc/bash.bashrc for everyone. Keep a copy of the file with your other config, because a reinstall from a fresh template starts with the stock one again. For flags worth aliasing, the grep guide and the Linux commands cheat sheet are good places to start, and the echo guide covers the quoting rules that also decide what ends up in an alias.

Frequently asked

How do I make an alias permanent in Linux?

Add the alias line, for example alias ll='ls -alF', to ~/.bashrc. On Debian and Ubuntu you can also use ~/.bash_aliases, which the default ~/.bashrc of normal users loads (Debian's default root .bashrc does not). Then run source ~/.bashrc or open a new terminal. For zsh use ~/.zshrc. An alias typed only at the prompt is gone when the shell closes.

How do I pass arguments to a bash alias?

You cannot. An alias only replaces text, and whatever you type after it is appended at the end. When the argument has to go somewhere in the middle, write a shell function instead, for example mkcd() { mkdir -p "$1" && cd "$1"; } in ~/.bashrc.

How do I run a command without its alias?

Put a backslash in front of it (\ls), use command ls, quote the name ('ls') or call the full path (/usr/bin/ls). type -a ls shows whether ls is an alias and which file it would otherwise run.

Why does my alias not work in a bash script?

bash does not expand aliases in non-interactive shells, which includes every script. Use a function in the script, or put shopt -s expand_aliases on its own line before the alias is defined and used. dash, which is /bin/sh on Debian and Ubuntu, does expand aliases in scripts.

Related articles

All guides