NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: standards/42828: Almquist shell always evaluates the contents of ${ENV} even if non-interactive
The following reply was made to PR standards/42828; it has been noted by GNATS.
From: Richard Hansen <rhansen%bbn.com@localhost>
To: Robert Elz <kre%munnari.OZ.AU@localhost>
Cc: gnats-bugs%NetBSD.org@localhost, standards-manager%NetBSD.org@localhost,
netbsd-bugs%NetBSD.org@localhost
Subject: Re: standards/42828: Almquist shell always evaluates the contents
of ${ENV} even if non-interactive
Date: Mon, 22 Feb 2010 18:07:46 -0500
> Now that you know how NetBSD applies $ENV, I would assume that you have
> no further problems - ie: for this usage, the difference from other systems
> is a minor annoyance, not a serious impediment.
Correct; it's an annoyance and not a serious impediment. I'm arguing
for a fix to remove that annoyance.
> If you had examples of the latter where NetBSD's application of $ENV
> was a problem I'd be much more tempted to agree to a change, for the sake of
> compatibility, for just user setup files, I'm not.
The annoyance is the problem. It's not a severe or urgent problem, but
it is a problem.
I would like to reach consensus on whether the benefits of fixing the
annoyance outweigh the costs. The benefits aren't huge because the
annoyance isn't huge, but I argue that the costs of fixing this are small.
Benefits:
* reduced risk of login shell freezes caused by fork bombs
* faster shell invocation for scripts
* standards compliance/meets user expectations
* reliable initial execution environment for scripts
Costs:
* implementing the fix (already done)
* backward incompatibility (only affects users that have code in
their ${ENV} file that is evaluated by non-interactive shells)
* makes some tasks less convenient
Is there anything I'm forgetting?
>
>> Would you be willing to take this up with the POSIX working group?
>
> I don't have the time either ... and in any case, I've pretty much given
> up on the current set of standards bodies - they've all become full of
> people for whom the standard is what is most important, rather than the
> systems that are built using the standard (ie: making the standard itself
> seem better looks to me to be of greater importance than making the system
> that uses the standard actually work better.)
This criticism brings up a broader question: How much should NetBSD
care about POSIX compliance?
I agree that standards committees can sometimes fail to appreciate
real-world issues in their zeal to create a theoretically better world
(see the controversy around C++98's 'export' feature [1]), but I do
appreciate the uniformity and long-term perspective they provide.
I think a POSIX violation should be classified as a bug. It might not
be fixed if there isn't enough manpower or user interest, but it should
still be considered a bug.
[1] <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf>
>
>> Flawed implies that there are legitimate use cases that are not
>> supported,
>
> flawed just implies there is a defect - something that could be improved,
> or which is less than perfect.
I like to distinguish "design flaw" from "implementation flaw". I
define a design flaw as something that precludes any implementation from
meeting a requirement (such as a use case that must be supported).
I don't think there is a requirement to evaluate ${ENV} for
non-interactive shells. It might be handy in some cases, but I can't
think of a case where it would be needed. That's why I prefer the word
"suboptimal" over "flawed".
>
>> but I have not yet come across any such use cases. Can you
>> provide an example where a user needs ${ENV} evaluated upon invocation
>> of every non-interactive shell?
>
> "of every non-interactive shell" ? No, of course not, but that's not
> what is needed - the converse of "only used by non-interactive shells"
> is "used by at least one non-interactive shell" (ie: the opposite of
> "none" is "one" not "all").
Let me rephrase by using an example: Suppose a user needed to change
the behavior of one particular shell script. In NetBSD, there are three
ways this might be done:
1. modify the script
2. via ${ENV}
3. change the invoker's environment (e.g., export environment
variables, open/close file descriptors, etc.) before running the script
Option #1 may not be available. Maybe the file is not writable, or
maybe modifications are too impractical (e.g., upgrading the package
providing the script will revert any changes). Option #2 is not
available on other platforms and may have unintended consequences in
other scripts. Option #3 may not be powerful enough.
The big question: Do options #1 and #3 provide enough flexibility in
practice? If so, then option #2 is not needed and we should fix this
bug. Certainly options #1 and #3 are insufficient in come cases, but I
would argue that those cases are rare and the result of an exceptional
flaw that should be dealt with in another way.
>
> And that's easy - I make scripts (personal use scripts) all the time
> by simply cut and paste from my history - that is, whenever I detect that
> I'm going to re-execute a set of commands that I have done in the not
> too distant past, I assume that if I'm doing it twice, I'm going to be
> doing it again, so I simply take what I did and stick it in a script, then
> run the script. That's a non-interactive shell running the script, and
> in order to run correctly, it needs to run with the same environment that
> my interactive shell where I first ran the commands had - that is, it
> needs to have access to whatever is in ${ENV} because my interactive shell
> had that access as well.
>
> And yes, of course, I can ". ${ENV}" in the script, but then I need to
> remember I have to add that, every time.
This is an example of where NetBSD's behavior is handy but not needed.
If this bug was fixed, you could still make your scripts work.
For this particular example, current behavior vs. fixed is a tradeoff
between having to remember to add the following at the top of the ${ENV}
file:
case "$-" in *i*);; *) return;; esac
versus having the remember to add the following to the scripts:
[ -r "${ENV}" ] && . "${ENV}"
Either one is annoying, but fixing it is standards compliant and won't
cause your login shell to lock up if you forget the magic line.
>
> Another use, that is less common for me, but I have done on occasion,
> is to define shell functions that replace standard commands, and either do
> something compatible, but in a different way (like turning "rm" into
> a "mv" to a trash directory) or add trace/debugging to what is happening,
> so allow debugging of complex sets of scripts to find out just where the
> script is doing something it shouldn't be doing, and why. For that, I
> can set ENV so a suitable environment is established for the scripts that
> I want to investigate - but only if they respect it.
This is another example of where NetBSD's behavior is handy but not
needed. The same results can be achieved by prepending a special
directory to PATH and populating that directory with custom versions of
standard commands.
>
>> Perhaps the flaw is in NetBSD's design: The ${ENV} file can arbitrarily
>> modify the shell execution environment (change the working directory,
>> modify positional parameters, close file descriptors, trap signals,
>> define functions, set shell options, etc.). This means that shell
>> script writers can't rely on a consistent initial environment.
>
> Huh? They can't rely upon most of that anyway - when the shell that starts
> the script begins, the environment can be anything.
You're right about file descriptors, but the others have well-defined
initial values. Changing them in ${ENV} could cause problems. Here are
some (somewhat silly) examples to illustrate the potential danger:
* working directory: Initially the current directory matches the
working directory of the invoker. If the user adds 'cd "${HOME}"' to
the ${ENV} file, then every shell script will assume it was invoked from
${HOME}.
* positional parameters: Initially the positional parameters match
the command line arguments passed by the invoker. If the user adds
'shift' somewhere in the ${ENV} file, all shell scripts will ignore the
first command line argument.
* shell options: Initially they're all turned off. If the user adds
'set -C' to ${ENV}, '>' will no longer work as expected for every shell
script.
> Any of that that is important to the script needs to be explicitly either
> tested, or set, in the script, to ensure the environment is as it expects.
Shell scripts could use $- to test for sane shell options, but none of
them do. (Why would they? The POSIX spec says they're all turned off
by default.) Shell scripts can't tell if the current working directory
or positional parameters were modified so there's nothing to test or set.
>> It is doubtful this would be a significant problem in practice, but in
>> theory this could lead to bugs that appear to be in a script file but are
>> actually caused by the user's ${ENV} file.
>
> Yes, of course it can. If you put stuff in there that breaks things, you
> get what you deserve (just the same as if you put commands in directories
> early
> in your PATH with standard names but which don't do what the standard
> commands
> with the same names do). You're entitled to break things if you want to.
> So is any other user.
If a user's ${ENV} file follows the POSIX spec, it is reasonable for the
user to expect it to work; the user doesn't "deserve" to have the login
shell lock up.
>
>> but only if the
>> community respectfully deals with legitimate user complaints.
>
> I agree, but you need to understand that there's more than one way to
> deal with a problem - simply making every change everyone asks for,
> regardless of whether that change makes things better or not would
> hardly be a responsible attitude, would it? Nor does it mean that
> whatever POSIX says is necessarily correct for us.
I do not mean for respect to entail capitulation, only that the tone be
professional and not condescending or dismissive.
-Richard
Home |
Main Index |
Thread Index |
Old Index