0

If two different directories in the PATH environment variable both contain a binary with the same name (but slightly different behavior), are there specifications/guarantees on which one will be used?

On my machine (macOS Monterey, Darwin 21.2.0) I observed (via which <binary name>) that the binary is chosen from the first directory found in PATH (reading its content left to right). But is this standard behavior across all Linux/UNIX-ish OSes? i.e. is there some standard that enforces it (e.g. POSIX)?

Extra context (for the curious ones): I'm writing a project that has a script that downloads a custom version of a standard binary in a project-specific folder and then invokes another script that MUST use the custom binary rather than the regular one. I'm adding the folder with the custom binary to PATH before invoking the second script. Given what I've observed on how PATH is searched in case of collisions, I'm setting PATH as PATH=<my-custom-folder>:$PATH rather than PATH=$PATH:<my-custom-folder>. But this project has multiple collaborators, and I want to make sure that we all run the same binary. If different OSes searched PATH in ways different than mine, things would break.

8
  • 2
    AFAIK, most shells invoke the first matching binary they find, without searching the remaining directories in $PATH.
    – Sotto Voce
    Dec 12, 2023 at 23:06
  • It's not specifically a shell thing, @SottoVoce; it's defined and built in to the exec(3) family of library calls Dec 12, 2023 at 23:51
  • @ChrisDavies If I read the man page correctly, Bash may circumvent the exec call. If the standard command has already been called by this shell, the absolute path of the command will have been hashed, and Bash will pass this to exec(3), which will not even search the modified PATH. The hash needs to be explicitly revoked with hash -r or hash -d name. Dec 12, 2023 at 23:57
  • Fair point, @Paul_Pedant. I've amended my answer to provide a specific reference to shell execution w.r.t $PATH Dec 13, 2023 at 0:02
  • 1
    @FelixJN, yes. But I've also used this PATH search guarantee sometimes to override system applications. rename is one, for example. Either with newer versions that I can't get through the package manager, or on rare occasion by changing behaviours (providing extra options for things that I do regularly) with a simple shell script that then calls the real binary Dec 13, 2023 at 8:13

1 Answer 1

4

POSIX defines the library calls execlp(3) and execvp(3) as searching the environment variable PATH for the location of the specified executable. (Unless the executable has a relative or absolute path specified for its name, such as /bin/ls or ./a.out, that is.)

The POSIX definition of PATH is such that,

This variable shall represent the sequence of path prefixes that certain functions and utilities apply in searching for an executable file known only by a filename. The prefixes shall be separated by a ( ':' ). […] The list shall be searched from beginning to end, applying the filename to each prefix, until an executable file with the specified name and appropriate execution permissions is found.

A POSIX shell must also follow (part 1e) this approach, even if it does not directly defer searching the $PATH to one of the exec(3) functions.

So to answer your question directly, if you have an unqualified command (such as ls), the first executable found in a directory specified in the list contained in $PATH will be used. Not necessarily a binary as scripts can also be executable. (If the command contains / in its pathname then it is used directly, with the current directory being the starting point for a relative pathname.)

Thinking more about your underlying requirement. Perhaps you should define your own environment variable (MYAPP_DIR, for example) that points to the directory holding your application's executables. You can then invoke the equivalent of $MYAPP_DIR/myutility rather than relying on the user's $PATH to be correct at all times.

You must log in to answer this question.

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