40

When a file is executed, how does Unix search for it? If there are multiple executable files in PATH with the same name, which one is preferred? Is the current directory included in the search when a file is executed?

Suppose there is a file with name executable.sh in the current directory. Would that work if it is executed $ executed and . is not part of the PATH?

40

The $PATH is searched from beginning to end, with the first matching executable being run. So directories at the beginning of $PATH take precedence over those that come later. Executables in the current directory (.) are only executed if . is in $PATH (which it usually isn't). There is no implicit inclusion of the current directory in the search path.

  • It's weird that, my $PATH don't contains ., but it seems would search from current dir first, before check dirs defined in $PATH itself. – Eric Wang Feb 3 '17 at 16:24
17

For files in the current directory, you will want to precede them with ./, so the command would become ./executable.sh. You should never have . in your PATH as it poses a security risk, among other problems.

Directories that come first in the PATH and searched first.

The overall order for searching is like this if I remember correctly:

  • aliases

  • exported functions

  • built-in shell commands

  • scripts and binaries in your PATH

  • 7
    I'd add the hash - remember bash (and maybe other shells) keep a hash of recently used commands to make finding them easier. Sometimes you have to purge the cache (using hash -r) if you change your PATH or program locations. – Rich Homolka Jan 28 '11 at 23:34
  • 3
    +1 for the order of searching. Would be nice if you could remember the source of information :) – twan163 Dec 14 '16 at 18:08
7

Though this has been answered well by some others, I'd like to add some thoughts:

1) PATH is only consulted if the executable invoked has no path elements in it. somecommand would be looked up in $PATH, ./somecommand or /usr/bin/somecommand, or ../../bin/somecommand just use directory rules, not PATH

If there are multiple executable files in PATH with the same name which one is preferred?

It stops at the first one it finds, reading $PATH left to right.

Is current directory included in the search when file is executed?

If the current directory is in PATH then it is searched. Remember that an empty directory in PATH includes the current directory. e.g. PATH=:/usr/bin (leading empty) PATH=/usr/bin: (trailing empty) and PATH=/usr/bin::/bin (middle empty) will all effectively include current working directory.

Suppose there is a file with name executable.sh in a current directory. Would that work if it is executed $ executed and . is not part of the PATH?

It would never find it by searching PATH. If current dir is not in PATH, it won't find it by a PATH lookup.

That said (and sorry to add confusion) if there was an alias or function that ran the command, it would be run. Or if your shell had a location cache, and the executable was in the cache, it may find it. So, it will never find it in PATH, but it may be run by other means.

  • Thanks for the cache note, it almost drive me crazy that the old executable in /usr/bin/ is still invoked not the new one in /usr/local/bin, however it is on the left in the $PATH till I logged out, and logged in again. – the accountant Apr 18 at 14:23
  • 1
    @theaccountant in bash you can do ‘hash -r’ to clear the shell cache – Rich Homolka Apr 18 at 18:28
3

To see what your path currently is just type echo $PATH, or printenv PATH.

Then you'll know the order of searching. If you have multiple files with the same name, just run which ____ to see.

Ex.

system#> which grep

/usr/bin/grep

a cool way to find files that work like your target is to use apropos:

apropos grep

bzgrep (1) - search possibly bzip2 compressed files for a regular expression

egrep (1) - print lines matching a pattern

fgrep (1) - print lines matching a pattern

grep (1) - print lines matching a pattern

and so on...

  • 2
    Oh yeah -- I forgot the whereis function to find ALL instances of a file: > whereis grep – mbb Jan 28 '11 at 16:42
  • grep: /bin/grep /usr/bin/grep /usr/share/man/man1/grep.1.gz – mbb Jan 28 '11 at 16:42
  • whereis uses a hardcoded list of locations, not $PATH. – grawity Jan 28 '11 at 20:45
  • @grawity Could you expand on that? – WinEunuuchs2Unix Nov 9 '18 at 1:09
-2

@coneslayer- The default order of finding executable is the current path, built in commands and then the $PATH. So if a function named executable already exists in the pwd, then that is executed.if not then the precedence searches for built in commands of shell and then $PATH

  • If you were talking about the Thompson shell, the Mashey shell, or some other fossilized holdover from 40 years ago, you might be right.   But no current, mainstream Unix shell searches the current directory automatically. – Scott Jul 12 '18 at 17:36
  • @Scott So the default search path for a command is first built in and then $PATH and searches the CWD only if I give ./ ? Am i right? – proc Jul 12 '18 at 17:42
  • Well, aliases, functions, and builtins.  Then, if you specify a path with the command (including ./), it searches that directory only; otherwise, it searches $PATH. – Scott Jul 12 '18 at 17:47

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.