I'm assuming it has something to do with when the program to run is created, it is associated with the working directory where it was created ?
2 Answers
Assuming you are calling the program without a full or relative path and the program is not a function or built-in, it must be in your PATH environmental variable in order to be found.
3.7.2 Command Search and Execution
Bash uses a hash table to remember the full pathnames of executable files to avoid multiple PATH searches (see the description of hash in Bourne Shell Builtins). A full search of the directories in $PATH is performed only if the command is not found in the hash table. If the search is unsuccessful, the shell searches for a defined shell function named command_not_found_handle. If that function exists, it is invoked in a separate execution environment with the original command and the original command’s arguments as its arguments, and the function’s exit status becomes the exit status of that subshell. If that function is not defined, the shell prints an error message and returns an exit status of 127.
-
If you want to see the full path yourself, you can run
which program
, for examplewhich wget
might return something like/usr/bin/wget
. Nov 25, 2020 at 2:41 -
In your answer you talked about how Bash searches in $PATH. But what about something that's not Bash? A binary for example, let's say the binary /bin/which. How does that binary know where to search in order to do it's job? I don't suppose it consults Bash for paths? There may not even be any Bash on that machine, and yet
which
will still do its job. How?– PourkoNov 25, 2020 at 5:07 -
@Pourko A binary will call one of the
exec()
library functions. That function will search$PATH
just like the shell does.– Kusalananda ♦Nov 25, 2020 at 9:00 -
@Kusalananda Are you telling me that a binary like
which
is actually going to somehow search for Bash's $PATH variable?– PourkoNov 25, 2020 at 9:46 -
1@Pourko What makes you think
PATH
belongs tobash
? It's an environment variable, accessible by any process. It will be set before you startbash
. Yourbash
session may change it, but it doesn't in any way "belong" to it.– Kusalananda ♦Nov 25, 2020 at 9:47
When a program is executed the invoking program (typically a shell), by convention, searches for the program in the directories listed in the PATH
environment variable. To do this, the invoking program can use library functions like execlp
, execvp
, or execvpe
, which do the search, or the invoking program can implement similar logic itself.
The library functions eventually call the execve
system call, which is the workhorse that actually executes the program. The execve
call takes a file name as first parameter, which is the name of the file containing the program. The name is usually an absolute path to the file, but is can also be a relative path. In this case the search for the file is done starting from the process's current directory. (Note that the file is not necessarily contained in the current directory: the name can be, for instance, ../../myprogram
.) The execve
system call does not care about the PATH
environment variable.
So, how does the kernel know the absolute path to the program if a relative path is given to the execve
system call? The answer is that it doesn't, and it doesn't need to.