Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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)

share|improve this question
    
As a side note, it's typically more helpful to people answering if you provide your version of bash, rather than OS version when asking a question specific to bash. –  jordanm Oct 18 '12 at 6:46
    
@jordanm Updated. –  user13107 Oct 18 '12 at 6:50
add comment

5 Answers 5

up vote 5 down vote accepted

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

alias | sed 's/^[^ ]* *\|=.*$//g' | while read a; do
  printf "%20.20s : %s\n" $a "$(type -ta $a | tr '\n' ' ')"
done | awk -F: '$2 ~ /file/'

Explanation

alias alone lists defined aliases and sed extracts their name. The while loop runs type -ta on each of them and awk prints the lines that both contain alias and file.

share|improve this answer
add comment

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

share|improve this answer
    
For example, type ls prints ls is aliased to `ls --color=auto' here. –  l0b0 Oct 18 '12 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 '12 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 '12 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 '12 at 8:38
    
@math: The original question is tagged /bash. –  choroba Dec 18 '12 at 12:58
add comment

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.

EDIT

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 -

share|improve this answer
    
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 '12 at 6:31
    
@user13107 updated the answer –  warl0ck Oct 18 '12 at 6:47
    
Thanks. How do I unset tracing? –  user13107 Oct 18 '12 at 6:53
    
@user13107 updated again ;-P –  warl0ck Oct 18 '12 at 6:57
1  
"there's no way to list the conflicts" - you're just not imaginative enough. –  camh Oct 18 '12 at 10:17
show 1 more comment

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.

share|improve this answer
add comment

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.

share|improve this answer
    
Thanks. This is certainly useful, but not able to see how it finds the conflict creating aliases. –  user13107 Oct 18 '12 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 '12 at 6:57
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.