[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Doc of "set -e" should mention non-locality

From: Rainer Blome
Subject: Re: Doc of "set -e" should mention non-locality
Date: Wed, 04 Jul 2012 17:37:25 +0200

-------- Original-Nachricht --------
> Datum: Fri, 29 Jun 2012 18:03:13 -0500
> Von: Dan Douglas <address@hidden>
> An: address@hidden
> CC: Rainer Blome <address@hidden>

Remember that my main suggestion is to clearly document the intended
behavior (see the subject). This could mean to add a generic
paragraph to the documentation of "set" that describes the scope
and extent for all options.  Something like this:

In Bash, "set" options act on a global scope per shell process,
they do not respect shell function scope.
The effect of turning on a "set" option starts after the "set -" command 
The effect of turning off a "set" option starts after the "set +" command 

For "set -e", I would add this:
Conditional statements such as while and if have the effect of temporarily 
suppressing the effect of any "set -e"
in effect while the condition is evaluated.
Thus, when a shell function is run as part of the evaluation of a condition,
"set -e" will not be in effect while in the function.
Any use of "set -e" within such a shell function immediately changes
the global flags ($-), but will otherwise
take effect only after the condition is evaluated.

> On Thursday, June 28, 2012 02:37:17 PM Rainer Blome wrote:
> > The implementation of "set -e" does not respect "lexical nesting".
> > This can be very surprising.  
> None of the "set" options do, nor does the ERR trap.

That may very well be. Is this documented anywhere?

It can still be surprising, for several reasons:

* The wording in the current documentation is easy to misunderstand.
It is not clear what "part" means.
In other programming languages, "part" often respects lexical nesting.
This makes it easy to make a false assumption.
See my first mail.

* Different POSIX shell implementations are free to behave
differently, because the behavior is not specified exactly.
does not mention scoping or extent, except in the section about "-e".
The section does not specify whether the commands that make up
a shell function are considered part of the calling command or not.
At least I did not see anything like that.
In my view, this point is under-specified,
or at least specified not clearly enough.

* Some shell implementations *do* behave differently from Bash
in this regard. At least on AIX, ksh and sh do so.

* The average shell programmer probably seldomly encounters
the difference, because it rarely matters.
Because of this, the issue is not well-known.

> That would make this the exception.

As I said, I suggest to clarify the documentation.

Regards, Rainer

PS: Your suggested "workaround" is, well, hard to understand.
Reminds me of the way people extend FORTH by massaging the stacks.
You have to know exactly what is parsed, substituted and evaluated
when in order to understand this (if it even works, did not try it).
I would not dare use this in production for fear of
receiving a beating from colleagues over hard to maintain code. ;-)

> Here's a workaround (untested).
> sete() {
>     [[ $- == *e* ]]  && return 1
>     trap "$(</dev/stdin)" RETURN
> } <<EOF
> if [[ $FUNCNAME != \$FUNCNAME ]]; then
>     set +e
>     trap - RETURN
> else
>     set -e
> fi
> This will "set -e" in only the scope of the caller. It gets a bit more 
> complicated if you want to use this RETURN feature more extensively and 
> preserve other possible RETURN traps, but most people won't have to worry 
> about that.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]