[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: bin/48843: sh(1): break/continue/return broken inside dot commands
The following reply was made to PR bin/48843; it has been noted by GNATS.
From: Richard Hansen <rhansen%bbn.com@localhost>
To: David Holland <dholland-tech%netbsd.org@localhost>
Cc: jarmo.jaakkola%roskakori.fi@localhost, gnats-bugs%NetBSD.org@localhost,
Subject: Re: bin/48843: sh(1): break/continue/return broken inside dot commands
Date: Mon, 02 Jun 2014 13:54:04 -0400
On 2014-05-31 19:51, David Holland wrote:
> On Sat, May 31, 2014 at 05:14:26PM -0400, Richard Hansen wrote:
>>> Whether break and continue should work from the sourced
>>> file might be debatable. Because the dot command says "in the current
>>> environment", I'd say yes.
>> Not necessarily. POSIX does not define "enclosing loop", so it could be
>> interpreted as syntactic enclosure (a break/continue command must be a
>> command in the compound list associated with the loop for the loop to
>> qualify as enclosing the command) or logical enclosure as experienced
>> during execution. I can see pros and cons to either behavior.
> Offhand, I would say that continues and breaks should be statically
> scoped; dynamic scoping is almost always a mistake. So you certainly
> shouldn't be able to break from a loop by calling a function that
> contains a break outside a loop. (Although netbsd's sh, bash, and zsh
> all seem to allow this, I would call it a bug. ksh rejects it.)
I think I also prefer lexical scoping, but I can see some valid (though
unusual) uses for dynamic scoping.
> How this applies to a sourced file isn't so clear though, at least
> offhand, as the point of sourcing a file is to read and evaluate it
> within the current context.
Yes and no -- there are subtle differences between the dot command and
C's #include preprocessor directive (exit status of the dot command,
in-line variable assignments before the dot command, redirection).
> My inclination would be that sourcing a
> file is not the same as calling a function; however, I'm far from an
> expert on sh.
I don't really know the history, but my impression is that the dot
command was intended to make it possible to split common complex tasks
out into modular, reusable scripts. That sounds more like a function
and less like a preprocessor include to me, though the differences
aren't very significant.
> It seems that the behavior of sourcing with respect to $0 and $@
> varies among implementations, which doesn't make me happy.
They're all consistent if you don't specify any additional arguments to
the dot command. Zsh does something different with $0, but it's an
incompatible scripting language in many ways unless run in sh emulation
mode (e.g., it doesn't do word splitting by default -- a drastic
departure from POSIX shell).
>> I will bring this up during the next Austin Group teleconference. We
>> should be able to get some improved wording in before POSIX Issue 7 TC2
>> is published (even if that wording is simply "unspecified" or
>> "implementation defined"). Any input from the NetBSD community would be
>> The intended behavior of break/continue outside of a loop is also
>> unclear. I'll bring that up as well.
> netbsd's sh seems to accept it silently; ksh, bash, and zsh all reject
> it. I would consider our sh broken.
Yes, although not necessarily non-conformant. I'd say that the behavior
of break and continue outside of a loop should be specified as
undefined, which would allow implementations to do whatever they want
(error out, silently ignore it, give it a special meaning as a fancy
>>> Because I read the standard to mean that break and continue should have
>>> an effect outside the sourced file, that's how I implemented it. For what
>>> it's worth, this also seems to be what bash does.
>> The behavior of existing implementations will strongly influence the
>> direction the Austin Group takes when revising the text. With that
>> said, what behavior would you like POSIX to specify?
> With stuff like this, I'd rather fix our implementation (or have it be
> noncompliant until fixed) than standardize unprincipled behavior. FWIW.
OK, so that's one one vote for static/lexical scoping.
Note that unlike variable binding, the behavior of dynamic scoping of
break/continue is a superset of static/lexical scoping (assuming no
closures): If the shell does dynamic scoping of break/continue but
scripts are always written assuming lexical scoping then those scripts
will still work as expected in all cases. If POSIX were to specify
static/lexical scoping then a shell that performs dynamic scoping would
be conformant but with an extension to the standard.
Main Index |
Thread Index |