I am reading Sobell's A Practical Guide to Linux Commands, Editors, and Shell Programming, 4e, and I am currently starting Chapter 5 on the basics of shells.
On page 135 Sobell explains that
From the command line, there are three ways you can specify the name of a file you want the shell to execute: as an absolute pathname (starts with a slash [/]; page 90), as a relative pathname (includes a slash but does not start with a slash; page 91), or as a simple filename (no slash).
Further, he writes that
When you specify a simple filename (no slash), the shell searches through a list of directories for a filename that matches the specified name and for which you have execute permission. The shell does not look through all directories but only the ones specified by the variable named PATH.
Importantly, he notes that the working directory is generally not part of PATH.
My question is therefore about understanding how (why?) the shell seems to behave differently based on whether a simple filename is passed as a command versus an argument to a command.
Up until this point in the book, I have understood simple filenames to simply be a special case of relative paths wherein we don't need a slash because the given file is directly a child of the working directory. Thus, for example, if I have a file named foo
in my home directory and I am in my home directory, then
ls -l foo
will give me detailed information about foo
(I have passed foo
, a simple filename, as an argument to ls
).
Now it seems that the behavior is different with respect to commands which are themselves programs/files/executables (you'll forgive my naivete and lack of precision here I hope). When I simply give the following to the command line, Sobell seems to be saying that the shell looks through directories in the PATH and not through the working directory necessarily (unless that is part of PATH):
ls
That is, in the specific case that a simple filename is given as a command rather than as an argument, the behavior of the shell in terms of where it looks is different. Is this understanding correct?
ls
. In the first example,foo
is an argument and completely uninvolved in the finding of thels
file which is what the command is wanting to execute. – Kusalananda Jan 25 '24 at 19:59PATH
, an executable hello inside of that directory needs to be started with the command./hello
if the current directory is $HOME/src/hello-0.1, orhello-0.1/hello
if $HOME/src is current directory, or$HOME/src/hello-0.1/hello
in general. Shells with tilde expansion allow tilde (~
) to be entered instead of$HOME
. – Vilinkameni Jan 25 '24 at 20:20