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

EE18
  • 233
  • What makes you think the shell is searching PATH when given ./date? What's the evidence for that? – muru Feb 13 '24 at 01:02
  • I've attached the question which suggests this @muru – EE18 Feb 13 '24 at 01:02
  • Is that something you have actually run and verified? – muru Feb 13 '24 at 01: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 – EE18 Feb 13 '24 at 02: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 ..." – Kaz Feb 13 '24 at 02:36
  • I only brought up the question because I was asked about "what made me think" it, but I want to be clear that my question is about when the shell searches path :) @Kaz – EE18 Feb 13 '24 at 02:38
  • @EE18 I wouldn't even have expected the "expected output", I'd expect an error about the file not having execute permissions. – muru Feb 13 '24 at 02:42
  • Is that because newly created files don't have execute permissions by default? (I am very new to Linux, apologies.) @muru – EE18 Feb 13 '24 at 02:43
  • @EE18 yes. So unless there was existing date file with execute permissions, or you added those manually before executing, you should have got an error. – muru Feb 13 '24 at 02:45
  • I did in fact and forgot to mention that (I thought maybe it was my personal default but not a standard default). I did a chmod and then proceeded from there when I answered you originally above :) thanks again for all the help! @muru – EE18 Feb 13 '24 at 02:46
  • @EE18 also the author has listed an email address in the webpage for this book: https://www.sobell.com/CR3/, you can try reaching out to them to find out if this is a typo or something else. – muru Feb 13 '24 at 02:48
  • So, the question here seems to hinge on some book making some claim, and it doesn't seem there's any test that could have repeated the same result. Which means that the question turns back to "why is the book saying that", and, well, the only person who can answer that is the author of the book. Note that you've already asked one question here where it was shown the book wasn't entirely correct in what it claimed, so expecting it to be right in another context, even if it's against your senses. – ilkkachu Feb 13 '24 at 10:15
  • (The way it just says "Explain the following unexpected result" without telling what the reader is supposed to be looking at makes it even worse. Of course I'm not sure if the actual book uses formatting to tell apart user input and output from the computer, at least that would exclude some of the ways the question could be just a trick.) – ilkkachu Feb 13 '24 at 10:19
  • Additionally, the dot command in a POSIX shell may search the PATH for the file to source. – glenn jackman Feb 13 '24 at 14:37

2 Answers2

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.

Kaz
  • 8,273
  • Hah, that's a nasty way to make a trick question. – muru Feb 13 '24 at 02: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? – EE18 Feb 13 '24 at 02: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. – muru Feb 13 '24 at 02: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? – EE18 Feb 13 '24 at 02: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. – Kaz Feb 13 '24 at 03:06
  • Whenever I quote examples with standard input, I use the notation [Ctrl-D][Enter] to indicate where that was typed, though it doesn't actually appear. Otherwise it's confusing where the request ends and the program's response starts. – Kaz Feb 13 '24 at 03:07
  • Touche. Thanks so much Kaz! – EE18 Feb 13 '24 at 03:11
  • Another way is to use a single-quoted heredoc. Then copy and paste works exactly as you define. cat >f <<'EOF' / #!/bin/sh / date / EOF / chmod a+rx f / ./f – Chris Davies Feb 13 '24 at 11:31
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.)

muru
  • 72,889
  • 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! – EE18 Feb 13 '24 at 17:54