63

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?

1

5 Answers 5

60

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.

3
  • 1
    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
    Feb 3, 2017 at 16:24
  • @Eric, that's security consideration to not search current dir (as windows/dos dues). Only if user explicitly added ./ to command May 4, 2023 at 15:05
  • @coneslayer once that executable is found, are library binaries also searched starting from the beginning?
    – dank8
    May 17, 2023 at 0:48
21

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

2
  • 8
    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. Jan 28, 2011 at 23:34
  • 4
    +1 for the order of searching. Would be nice if you could remember the source of information :)
    – twan163
    Dec 14, 2016 at 18:08
10

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.

2
  • 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. Apr 18, 2019 at 14:23
  • 1
    @theaccountant in bash you can do ‘hash -r’ to clear the shell cache Apr 18, 2019 at 18:28
4

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...

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

@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

3
  • 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. Jul 12, 2018 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, 2018 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. Jul 12, 2018 at 17:47

You must log in to answer this question.

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