For some reason[*], I looked at sh(1) "Command Search and Execution" in POSIX (issue 7 2018 and then issue 8 2024).
Starting with the 7th issue (2018), and concerning a command without any slash, the behavior is: ---8<---i7 2018 a) If the command name matches the name of a special built-in utility, that special built-in utility shall be invoked. b) If the command name matches the name of a utility listed in the following table [edited; but the list is defined, no ellipsis], the results are unspecified. c) If the command name matches the name of a function known to this shell, the function shall be invoked as described in Function Definition Command. If the implementation has provided a standard utility in the form of a function, it shall not be recognized at this point. It shall be invoked in conjunction with the path search in step 1e. d) If the command name matches the name [XSI] [Option Start] of the type or ulimit utility, or [Option End] of a utility listed in the following table [edited, but no ellipsis either], that utility shall be invoked. e) Otherwise, the command shall be searched for using the PATH environment variable as described in XBD Environment Variables : i) If the search is successful: a) If the system has implemented the utility as a regular built-in or as a shell function, it shall be invoked at this point in the path search. --->8---i7 2018 >From the specification above, I'm puzzled about two things: regular built-ins and PATH search: In issue 7, built-ins are segregated in two groups: "special built-ins" and "regular built-ins", the latter being the complement of the former (a built-in that is not "special"). But in the spec, a regular built-in can only be invoked in e), that is the corresponding name file has to be accessible via the PATH. If it is not, one can not invoke a regular built-in? This may have sense for an utility required by POSIX (that _has_ to be provided), but there may be a regular built-in that POSIX doesn't speak about... And what does "a successful search" mean? From the referenced paragraph "XBD Environment Variables": ---8<---issue 7 2018 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. --->8---issue 7 2018 But this contradicts the use of the shell in the paragraph I'm talking about, since if the permissions can be stat'ed, the "executable" nature of the file can not be ascertained without exec'ing---and this test may flag the pathname as invalid, and will void the further requirement that the shell should try to execute a not executable file (supposed to be a script chunk without the shebang). So what does "found" mean, in this case? A regular file, accessible with the correct permissions, so an exception from the "PATH" paragraph rules? Furthermore, the spec says in "2.14. Special Built-In Utilities": ---8<---issue 7 2018 The term "built-in" implies that the shell can execute the utility directly and does not need to search for it. --->8---issue 7 2018 The proposition is for all built-ins. And this contradicts the paragraph where the built-in has to be searched for previously... It seems to me that POSIX has focused on not special built-ins implementing a required utility and that _these_ were the target of the quoted portions, forgetting that there may be other built-ins, that, in a POSIX compliant shell, could then not be used unless they appear in the PATH (this implicit linked to the POSIX utilities seems to me to be this: "The special built-in utilities in this section need not be provided in a manner accessible via the exec family of functions defined in the System Interfaces volume of POSIX.1-2017." i.e. not special built-ins have to be provided in a manner accessible via the exec family of functions.) The issue 8 2024 adds to the fun... The d) has been simplified with the specification of "intrinsic utilities"---but this is still not "regular built-ins" in general. The variation is in e), the i.a) ---8<---issue 8 2024 if the system has implemented the utility as a built-in or as a shell function, and the built-in or function is associated with the directory that was most recently tested during the successful PATH search, that built-in or function shall be invoked. --->8---issue 8 2024 What does: "the built-in or function is associated with the directory that was most recently tested during the successful PATH search" mean? How is a directory "associated" to a built-in or a function, unless by the very finding of a corresponding filename (what type? What permissions? What content?) in a directory in the PATH search? Note: in the NetBSD implementation---I didn't look in the CSRG archives to see if these are in fact here from long ago---there are prefixes in the path: "%builtins" and "%func"; perhaps are these an attempt to this association? These are builtins or funcs if the prefix is specified as the preceding "dir" in PATH? Could somebody explain this in an "international" english, that is something a not english native speaker with an average english vocabulary could parse? TIA [*]: The reason why I looked at the spec is that, under Plan9, there is a feature that I find quite neat and consistent: utilities can be organized in subfolders and one can invoke from the shell (rc(1)) an utility like this: "ip/ipconfig ...". This organized the utilities in groups, instead of putting everything flat in a directory. I thus wanted to see how I could add this (it is not POSIX compliant) by setting an option, without disturbing much the POSIX behavior or introducing security problems that the POSIX spec had tried to address... -- Thierry Laronde <tlaronde +AT+ kergis +dot+ com> http://www.kergis.com/ http://kertex.kergis.com/ Key fingerprint = 0FF7 E906 FBAF FE95 FD89 250D 52B1 AE95 6006 F40C