-1

I am a bit confused about when PATH is searched. I had thought that PATH was only searched when a simple filename is given as the first token on a line, as in

$ date

A question I am solving however, seems to suggest that PATH is also searched when I very explicitly list a file with the ./ prefix:

$ ./date

Is this indeed the case? That is, if in my working directory I do not have an executable named date (say date was merely a script), the answer to this question seems to suggest that the shell will then go on to search PATH (and then find the standard date utility in some directory like bin).

I asked a somewhat analogous question here and the order for the shell search was nicely given in answer there. However, there I emphasized that I was simply giving the command as a simple filename. Here, I am very explicitly giving a ./ prefix. Why does the shell still search PATH, or am I missing something?


From Sobell's A Practical Guide to Linux:

Explain the following unexpected result:

$ whereis date
date: /bin/date ...
$ echo $PATH 
.:/usr/local/bin:/usr/bin:/bin
$ cat > date
echo "This is my own version of date." 
$ ./date
Sun May 21 11:45:49 PDT 2017

One "expects" that the shell script ./date is run so that the output is "This is my own version of date."

14
  • What makes you think the shell is searching PATH when given ./date? What's the evidence for that? Commented Feb 13, 2024 at 1:02
  • I've attached the question which suggests this @muru Commented Feb 13, 2024 at 1:02
  • Is that something you have actually run and verified? Commented Feb 13, 2024 at 1:13
  • I just got home to try it (I was reading on my phone previously). You're right, I do get the "expected" output. Do you think the question is in error and he maybe meant to have $ date as the command in the final line? @muru Commented Feb 13, 2024 at 2:29
  • StackOverflow is for questions about problems you're actually experiencing. This appears to be a question from a book: "From Sobell's A Practical Guide to Linux ..." Commented Feb 13, 2024 at 2:36

2 Answers 2

2

The POSIX-standard-conforming behavior with regard to PATH is not to use that variable if the input contains a slash anywhere. For instance if the command is foo, then the PATH is searched, but not if it is foo/bar or /foo/bar or ./foo/bar: anything with one or more slashes.

If a shell has to replicate PATH searching behavior in its own code base, rather than relying on functions like execvp, it should avoid searching when the input contains a slash.

I can reproduce your result easily, though.

Actual copy paste from my terminal:

$ cat > date
echo "this is my own version of date."
$ ./date
Mon 12 Feb 2024 06:38:20 PM PST
$

What I did was not type Ctrl-D after the echo ... line, so the $ ./date and the Mon 12 ... is all text typed into cat's standard input.

8
  • Hah, that's a nasty way to make a trick question. Commented Feb 13, 2024 at 2:40
  • I am super confused about how you reproduced it. Are you saying that you also appended $ ./date Mon 12 Feb 2024 06:38:20 PM PST to the file date? Commented Feb 13, 2024 at 2:42
  • @EE18 everything after the cat > ./date line is just input to cat. The $ in $ ./date is not a prompt, it's something Kaz actually typed in. Commented Feb 13, 2024 at 2:43
  • That seems like a crazy question! I suspect the author has just made an error and meant to use date rather than ./date, right? Commented Feb 13, 2024 at 2:45
  • 1
    Doesn't trip me up. With my decades of experience in this stuff, I readily came to the conclusion that if the echo ... line was put in into the file date in the current directory, even that that is a symbolic link, then ./date refers to that file. Therefore the ./date reference cannot be genuine. So who is to say that everything after cat > date isn't just dummy text pasted into its input? That reproduces exactly what you see, since the Ctrl-D isn't visible. Commented Feb 13, 2024 at 3:06
1

Looking only at the exercise quoted in the question, after thinking about it a bit, I think defining cat to be a function or script that does something other than the standard cat might also work. I found some online copies of the book, and this exercise has existed in the second, third and fourth editions, with the timestamp in the output changing, so I believe this is not a typo.

Depending on whether echo "This is my own version of date." in the third command is input or output, cat could be either:

cat () {
  read; # Reads a line of input, but we won't do anything with it
  echo date; # Write to stdout
  chmod +x /proc/self/fd/1; # Apply execute permissions to stdout's backing file
}

Or:

cat () {
  echo 'echo "This is my own version of date."' >&2 ; # Write to stderr
  echo date; 
  chmod +x /proc/self/fd/1;
}

The reason this works is:

  • /proc/self/fd/1 is a symlink to the actual file if stdout is redirected to a file.
  • chmod changes the permissions of the pointed-to file if given a symlink as an argument.

I checked the manpages Red Hat 4.2 (released 1997), and both of these hold true even back then (proc(5), chmod(1)), so these functions would have worked fine even going back to the first edition of the book. (Of course, the fake cat could have chmod +x ./date directly as well.)

1
  • Very weird exercise indeed. Thanks so much for taking the time out of your day to help me with it. I am suspicious that, from a pedagogical perspective, we should have date and not ./date as the intended command entered, but oh well! Commented Feb 13, 2024 at 17:54

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.