Is there a simple way to list all the command conflicts that have occurred in the system due to the bashrc update involving alias commands?

For example, someone writes alias ls=/path/to/user-generated/executable in bashrc. How does one find out that this is masking an actual command (ls). One way seems to be to run all the aliases before and after sourcing bashrc and diff the output. Are there any better ways?

I'm running Ubuntu 12.04.

bash --version

GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)


5 Answers 5


You can use type to find out how a command would be interpreted by bash.

  • 1
    For example, type ls prints ls is aliased to `ls --color=auto' here.
    – l0b0
    Oct 18, 2012 at 9:08
  • Same does work with which, but I don't now if both (type,which) shell builtins are the same.
    – math
    Dec 17, 2012 at 7:16
  • @math: type which tells you which is /usr/bin/which, so it is not a builtin. Therefore, it cannot tell you whether something is a builtin or not (e.g. which echo versus type echo).
    – choroba
    Dec 17, 2012 at 8:21
  • I guess it depends on the shell you use: type which which is a shell builtin I am using the zsh.
    – math
    Dec 17, 2012 at 8:38
  • @math: The original question is tagged /bash.
    – choroba
    Dec 18, 2012 at 12:58

To find out what commands are masked by aliases, do something like this:

alias                            |
awk -F '[ =]+' '{print $2}'      |
while read cmd; do
  type -ta "$cmd" | grep -q file \
    && printf "%s is overloaded: \"%s\"\n" "$cmd" "$(alias $cmd)"


alias alone lists defined aliases and awk extracts their name. The while loop runs type -ta on each of them and grep checks if any also are a file.


As your first question, there's no way to list the conflicts, since bash use a hash table internally, it only records the last override.

To find out if a command is an alias, use alias ls in your case, if it tells you something like "not found" then it's not an alias, otherwise it is.

To launch original function disregarding the alias, prefix a slash, e.g \ls will launch the real hashed ls, ignore the alias.


If you want to know quickly if a command is an alias, you could enable debugging mode by set -x, now if you execute ls:

enter image description here

You'll see a debug output of the real command being executed

To unset the debug mode, use set -

  • Thanks. But didn't get the alias part. What if a user doesn't know that there exists a command (e.g. ls)? Only thing he seems to know after running alias ls is what is it mapped to and not what it was originally mapped with. I guess one will have to run all the commands with and without \ to find conflicts.
    – user13107
    Oct 18, 2012 at 6:31
  • @user13107 updated the answer
    – daisy
    Oct 18, 2012 at 6:47
  • Thanks. How do I unset tracing?
    – user13107
    Oct 18, 2012 at 6:53
  • @user13107 updated again ;-P
    – daisy
    Oct 18, 2012 at 6:57
  • 1
    "there's no way to list the conflicts" - you're just not imaginative enough.
    – camh
    Oct 18, 2012 at 10:17

You can use the shell debugging feature to see exactly what is happening when bash invokes an interactive shell. The following should show you all aliases that are assigned when an interactive shell is spawned from a login shell:

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
  • -x -> enable debugging
  • -l -> login shell
  • -i -> interactive shell
  • -c -> command

Running the command exit is required so that the shell returns. The -i is required in this case because bash would not set up an interactive environment to run a command otherwise.

Here is an example from my system:

$ bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
++ alias 'ls=ls --color=auto'
$ alias -p
alias ls='ls --color=auto'

In order to see what file was last sourced when the alias was assigned to determine the file it occurred, you can extend the grep:

bash -x -l -i -c 'exit' 2>&1 | grep -E ' (alias|[.]|source) '

This may return false positives, but should be fine if you are manually inspecting the returned the data. The number of '+' symbols in front of the executed command indicate the depth.

+ . /home/jordan/.bashrc
++ alias 'ls=ls --color=auto'
++ . /home/jordan/.foo
+++ alias t=test
++ alias t=test2

In this sample output, it shows that .bashrc sets an alias for ls, .foo aliases t, and then .bashrc overrides the previous alias of t.

  • Thanks. This is certainly useful, but not able to see how it finds the conflict creating aliases.
    – user13107
    Oct 18, 2012 at 6:55
  • @user13107 I added some more details that should be helpful. Setting an alias to a new value is not a "conflicting" alias. It's normal documented behavior, which is why a round-about way is needed.
    – jordanm
    Oct 18, 2012 at 6:57

You can use the bash builtin compgen to get a list of all the command and all the aliases using compgen -ac. Any command that is also an alias will be duplicated in this list, so the simple naive solution is to look for duplicates in the output of compgen -ac.

However, duplicates may also appear if a command is on the path twice. For instance, I have /bin/which and /usr/bin/which so compgen -ac will list which twice even though it is not an alias.

So what is needed is to get all the duplicates from compgen -ac and compare that to a list of aliases. Only duplicates that are also aliases are those aliases that hide commands. We can do this with the comm(1) command and with bash process substitution.

comm -12 <(compgen -a | sort) <(compgen -ac | sort | uniq -d) 

compgen -a | sort is the list of all aliases (sorted for comm). compgen -ac | sort | uniq -d is the list of all duplicates from the list of commands and aliases. comm -12 outputs only those lines that are common to both.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .