1. Overview

Shell programs often implement a command alias feature, which is when the shell replaces the first word of a command when an alias for it exists. This is handy in saving a few keyboard strokes when the commands are lengthy or frequently used.

It is possible for an alias to shadow an existing command when they share the same name. In such cases, we need to rely on workarounds in order to disambiguate the command.

In this tutorial, we’ll quickly go over some very basic usage of using aliases, and then we will study a few different methods to run commands that have been shadowed by an alias.

2. Aliasing

2.1. Command Alias

The most common form of aliasing is a command alias, which is a text replacement for the first word in a command. Let’s create some dummy directories and files and shadow the ls command:

$ { mkdir -p a b c; touch e f g; }
$ alias ls='echo foobar'
$ ls
# foobar

We can list the aliases in our shell session with a simple alias command:

$ alias
# alias ls='echo foobar'

2.2. Global Alias

In the zsh shell, we can also use another form of aliasing, known as global alias, to substitute text anywhere in the input:

$ alias -g t='foobar'
$ echo t
# foobar

3. Avoiding Alias Substitution

Sometimes we want the shell to ignore aliases when it’s interpreting a command. There are a few different methods that we can use to work around an obstructing alias.

Next, let’s see how we can use these different techniques to work around the ls alias that we configured in the earlier sections.

3.1. unalias

A simple unalias ls will remove the ls alias from our shell session, and we’ll be able to invoke the previously shadowed command:

$ unalias ls
$ ls
# a  b  c  e  f  g

Although an easy workaround, the disadvantage of this approach is that we will lose the alias from our shell session.

3.2. Quoting

Another technique is to remove the special meaning from the command by “quoting” it. A command is considered quoted as soon as any character in the string is quoted. Let’s see the three different ways that we can quote a command.

First, we can use an escape character (`\`) to preserve the literal meaning of the command:

$ \ls
# a b c e f g

Another option is to quote the command using single quotes (`’…’`):

$ 'ls'
# a b c e f g

We can use quote the command using double quotes (`”…”`):

$ "ls"
# a b c e f g

Quoting is a less-often discussed shell concept, and there are a few things to point out. We should know that it’s not necessary to quote the entire command for the shell to consider the command as quoted. The following quoting variations equally “quote” the ls command:

$ l\s
# a b c e f g

$ l's'
# a b c e f g

$ l"s"
# a b c e f g

We should also be careful to not mistakenly confuse an alias with a shell function, as shell functions are regular commands so quoting them will not have any effect:

$ function foobar () { echo helloworld; }
$ foo\bar
# helloworld

3.3. command (builtin)

The self-titled builtin command can be used to narrow the interpretation of a command to only executable files found in directories in $PATH or shell builtins. Let’s see how we can use command to ignore the ls alias:

$ command ls
# a b c e f g

3.4. Absolute Path

When an alias is shadowing an executable file, a straightforward solution would be to simply specify the full pathname of the executable file as the command. There are a few tools that we can use to locate an executable file in our $PATH directories:

We can use which to search for an executable file in our $PATH which matches the filename provided. If an executable is not found, then which will terminate with an exit code 1. Let’s see that in action:

$ which ls
# /usr/bin/ls
$ which foobar
$ echo $?
# 1

We can also use the type builtin command to understand how the shell would interpret a command:

$ type -a ls
# ls is aliased to `ls --color=auto'
# ls is /usr/bin/ls
# ls is /bin/ls

4. Conclusion

In this article, we’ve studied a few different methods to work around aliases that shadow existing commands.

Admittedly, it might be difficult to decide which of these methods is best. We suggest using the absolute path approach if the goal is to run an executable file that has been shadowed by an alias as it is the least ambiguous method.