0

Commands like cp and ls reside under /bin or /usr/bin.

Hypothetically, if we created another executable of the same name, how will Linux differentiate between them?

  • 3
    It'll execute the first one found according to $PATH. – dsstorefile1 May 25 '18 at 7:26
  • 2
    you will have to write the full path to executable /bin/ls and /usr/bin/ls – cmak.fr May 25 '18 at 8:03
  • 2
    "if we created another executable of the same name" created where? – muru May 25 '18 at 8:59
3

TL;DR: the shell stops looking once it finds something to run.


You ask how will Linux differentiate between them? By Linux, perhaps you mean the kernel, which understands, for example, magic numbers, and in general knows how to execute an executable.

I will leave that topic to others, and assume that you're asking about what happens when a shell runs a command that exists in more than one form.


One reason, and seemingly the one you're asking about, why there might be two commands with the same name, is that two files can have the same basename, for example:

/usr/bin/foo
/bin/foo

We can always differentiate two files by their full paths, because it's not possible for two files in a filesystem to have the same full path. cmak.fr made a comment pointing this out.

If you install or write your own executables you might choose to put them in ~/bin or /usr/local/bin. These locations are in your default PATH in Ubuntu. /usr/local/bin is at the start of the default PATH:

$ grep PATH /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"

and ~/bin is prepended to PATH if it exists:

$ grep -A3 bin ~/.profile
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

So I end up with this PATH...

$ echo $PATH
/home/zanna/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Since /home/zanna/bin comes before /bin in my PATH, if I put a command called chmod in ~/bin, and ran chmod, that executable ~/bin/chmod would be run instead of /bin/chmod, because the shell stops looking once it finds something, and if I want to run /bin/chmod, I will have to do exactly that: type the full path of the program I want to run.

This is really the end of a story we haven't mentioned the beginning of, because path lookup is the last thing the shell does when trying to execute a command, and having two files with the same name isn't the only way there could be two commands with the same name.

I am here going to talk about Bash, because it's the only shell I am reasonably familiar with. As far as I know, other shells will follow similar procedures. It's important to note though that many utilities on Ubuntu call /bin/sh rather than Bash, and while /bin/sh may by a symlink to /bin/bash, by default on Ubuntu it's to /bin/dash, and could be to any shell program installed.

The first word of a command is what the shell tries to execute - subsequent words are its arguments (which may be options, and may not be required).

Note that alias expansion is performed before all other expansions at the stage of breaking the command into words, several stages before command execution. This means that aliases always take precedence over other commands that may have the same name.

After tokenization and all expansions are completed, redirections have been set up, and variable assignment has been done, command execution starts.

If the first word contains /, the shell assumes that the word is a path, and tries to execute (afaik, gets the kernel to get the CPU to execute it or to call the interpreter for it, or if all else fails runs it as a shell script) the file at that path. If the file at that path doesn't exist, you get no such file or directory.

If the first word doesn't contain /, the shell will proceed to look for the command in this order, and will execute the first thing it finds and then stop looking:

  1. Is there a shell function with this name?
  2. Is there a shell builtin with this name?
  3. Is there a command in the hash table with this name?
  4. Is there a command in any PATH directory with this name?

So, searching PATH is the last resort. Note that PATH is searched in order, left to right. The first directory in PATH is searched before the last one, so a command in the first directory with the same name as one in the second directory will be executed rather than the second one.

Note also that when you use sudo, it sets PATH to one defined in /etc/sudoers as secure_path.

If you install/create an executable with the same name as a preexisting executable, you should be aware that this may affect other programs, not only stuff you are doing in an interactive shell. A typical example of this is Anaconda, which installs a version of Python and prepends its bin directory to PATH. System programs that call python and expect something in /usr/bin might break because they get the wrong python. In general, create executables with different names.

Defining shell functions and aliases generally avoids this problem, because these are only known to shells that read ~/.bashrc (or whatever file defines them), that is, interactive (Bash) shells.

You can see all the programs that might be run when you execute a command using the type builtin (assuming you haven't defined an alias or shell function called type!). Run with -a to see all possible commands with this name in the order the shell would find them.

$ type type
type is a shell builtin
$ type -a echo
echo is a shell builtin
echo is /bin/echo
$ type -a ls
ls is aliased to `ls --color=auto'
ls is /bin/ls

Thus, in general, commands are differentiated by how they are known to the shell, and the order in which the shell tries to execute the executable things it knows about. To know and control what command will be run when there is more than one possibility, you must understand how the shell calling it works.


Many thanks to Eliah Kagan for explaining this stuff to me in chat.

  • 1
    I think with some shells (like dash and zsh), if they fail to execute ~/bin/chmod, will continue looking in PATH for a matching command that will execute, eventually executing /bin/chmod. – muru May 25 '18 at 9:57
  • 1
    Other shells behave the same during executable look-up because they either use execvpe(3) from whatever libc is available or mimic its behaviour (e. g. to cache the full path of discovered executables). – David Foerster May 27 '18 at 9:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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