(0003306)
kre (reporter)
2016-07-24 02:23
|
Why not just mark -h as deprecated, and forget about this change?
It is, after all, a more or less useless (and underspecified) option
as it is now. Its definition is:
Locate and remember utilities invoked by functions as those
functions are defined
but as best I can tell, as a function is being defined, no utilities
are invoked, ever, so there is nothing to remember. Nor is it
specified anywhere what is the point (or effect) of this memory if
there was something to remember.
When if this language were to be corrected to say what it probably
means, which is, while parsing, to remember the location of utilities
that will be invoked by a function when it is invoked sometime later,
how is that supposed to be done in general, consider ...
fn() {
"$@"
}
what does -h cause to be remembed in that case?
Then, if we can ever work out just what we should remember (if anything)
we then need to figure out what to do with that...
For normal command invocation, the file system location (that is,
from the PATH search) of commands with no /'s in their names may
be remembered, until PATH is changed, when they are all forgotten
(this is really just an efficiency hack, and aside from perhaps
allowing the shell to fail to notice a utility newly installed
earlier in PATH than where the old one was previously found, should
be invisible to the user.) If this is the intent of -h , then
there's really no need, remembering the location of commands actually
invoked when the function is invoked, is a better solution.
So, that cannot be it, the only possible intent for this would be
so that something like
PATH=.:other:stuff
fn() {
cmd
}
where ./cmd exists, would turn "cmd" into the value of ${PWD}/cmd
at the time of definition. I can see some utility in that, but it
isn't reliable if any change to PATH would cause the memory to be
deleted. Nor is it a good idea (IMO) to create something which is
only practiclaly useful when "." is in PATH. If "cmd" was "./cmd"
then remembering its location (replacing "." with ${PWD}) would be
a most unusual operation.
There are all kinds of other issues - such as the relationship
between aliases and functions - most shells (I believe) interpret
aliases during function definition, so that in...
fn() { w true; d sleep 10; dd; }
alias w=while
alias d=do
alias dd=done
the aliases do not affect the function (which would run the 'w',
'd', amd 'dd' commands) but if the function is defined after the
aliases, then the function instead contains a while loop. But there
is nothing in the definition of aliases that requires this that I'm
aware of, it would be OK for a shell to take the above and implement
a while loop (expanding the aliases as the function is invoked.)
In that case, the word which is just "true" here is a utility invoked
by the function, so -h (if defined properly) should cause its location
to be remembered. But when the function was defined, the shell could
not possibly know that. The same for "sleep".
To use the same example, if -h were in effect, would that prevent the
aliases being expanded, as (on most systems) 'w' and 'dd' are utilities
that a PATH search will locate (and we could use something else instead
of 'd' and make it 3 out of 3...) If the function has 'dd' replaced
by /usr/bin/dd then the 'dd' alias would never be seen. Let's
say the function was instead
fn() { wh true; d sleep 10; dd; }
and the 'w' alias (defined later) was a 'wh" alias instead. Given
normal system commands, the lookup for 'wh' and 'd' will fail, so there is
nothing to remember in that case, so their aliases could be expanded
later, but 'dd' is a utility that should be found, so now we have
a function containing a while loop, with no "done" - but which was
not detected as a syntax error during parsing?
This actually makes another (unspecified) assumption of course,
which is that when a function is defined (with -h set) that a
utility that will (or might) later be invoked, which cannot be
found (at the time of function definition) should simply be
left as it is, and searched for later. But nothing anywhere
says that is what should happen, perhaps when -h is set, utilities
to be invoked by the function which cannot be found are intended
to give a "command not found" error at function definition time,
and the function definition should exit with status 127 ?
All of this is simply a gigantic quagmire, and (apart from that set
of shells that treat tne -h definition literally, and so make the
option a no-op - which is what the NetBSD shell does, and always
has (since it learned about -h at all), and always will, I expect)
I really cannot believe that there are any two (unrelated) shells that
implement -h the same way in all respects. That is, there is no
existing standard -h option that can be defined, just a whole bunch
of different ones.
That makes it a prime example for doing to it the same as was done
recently to "-o nolog", and retain the existence of the option but
explicitly state that shells may ignore it, and perhaps even make
the operation of the shell unspecified if the option is set.
In that case, it would be better to remove -h from the synposis,
than to add it to the later list. |
(0003881)
geoffclare (manager)
2017-11-16 17:26
|
Along with desired action, Change in set -h P2410, L77147 of 2016 edition:
Locate and remember utilities invoked by functions as those
functions are defined (the utilities are normally located when
the function is executed).
to:
[OB] Setting this option may speed up PATH searches (see [xref to XBD Chapter 8]).
This option may be enabled by default.[/OB]
On page 2413 line 77273 of 2016 edition (set RATIONALE), change:
The −h flag is related to command name hashing. See [xref to hash].
to:
The −h option is related to command name hashing. See [xref to hash]. The normative description is deliberately vague because the way this option works varies between shell implementations.
Earlier versions of this standard specified -h as a way to locate and remember utilities to be invoked by functions as those functions are defined (the utilities are normally located when the function is executed). However, this did not match existing practice in most shells.
On page 2847, line 93798 of 2016 edition (last paragraph of hash DESCRIPTION), change:
Utilities provided as built-ins to the shell shall not be reported by hash.
to:
Utilities provided as built-ins to the shell and functions shall not be reported by hash.
On page 2848, line 93830-93834 of 2016 edition (hash STDOUT), add to the end of the paragraph:
This list shall be cleared when the contents of the PATH environment variable are changed.
On page 3226 line 108276-108280 of 2016 edition (sh SYNOPSIS) add OB shading to all six occurrences of the h option letter. |