[Top][All Lists]

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

Re: Cleaning up bash releases at first directory level

From: Chet Ramey
Subject: Re: Cleaning up bash releases at first directory level
Date: Fri, 24 Mar 2023 12:26:39 -0400
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.8.0

On 3/22/23 6:44 PM, Koichi Murase wrote:
,2023年3月21日(火) 22:40 Chet Ramey <>:
On 3/20/23 11:18 PM, Koichi Murase wrote:

Otherwise, impractical and
problematic changes only requested by a single insistent person, like
`localvar_unset', would easily enter the codebase.

Are you sure you mean `localvar_unset'?

Yes, `localvar_unset' (and `localvar_inherit'),

localvar_inherit is part of a separate discussion about more or less the
same topic, which is how to make local variables acceptable to the POSIX
committee. But no more on that.

The discussions about dynamic scoping started in the 1990s, but heated up
around 2001 when we first started looking at crafting a specification for
local variables that would

1. achieve implementor consensus; and
2. be acceptable to the POSIX committee

The behavior of `unset' on local variables is part of that discussion.

but I have to admit
that I do not know the detailed history of the debate. The event I
remember is [1], which made me decide to actively participate in
discussions of bug-bash. Before this event, I had only submitted a few
patches and had been just reading discussions in the list without
participating in any discussions, so I probably don't remember
discussions before it very well.


You missed it by at least half a decade, as you subsequently discovered.

gives some of the history, which was already over 15 years old at the time.

I know that the code of `localvar_unset' has existed before

Before what? The code went in in March, 2018 -- after the discussion --
disabled by default, with the commented-out shopt option, and the option
was exposed in September, 2018 during the bash-5.0 testing process. It's
still disabled by default.

but had
not been exposed as a shell option `shopt -s localvar_unset' until
that discussion.

This is not the case. But in any event:

Naking it a shell option allows people to play with alternate behavior
they may prefer (`purer' scoping) and that POSIX may choose. If POSIX
chooses this behavior (unlikely, we're never going to get past dynamic
vs. static scoping :-/ ) then it will be easy enough to toggle it.

I'm not sure about the past discussions in
bug-bash/help-bash, but elsewhere, I observed many people who don't
even know what is dynamic scoping regard it as a bug and insist that
dynamic scoping is a ``design bug'' even after telling them about the
dynamic scoping. I wouldn't like to let such people break the dynamic
scoping model of Bash halfway.

I suppose I'm more in favor of giving people agency.

In the 2018-03 discussion, there was only one person (kre) who
requested the behavior. I think making requests is a good thing to
possibly improve the design but at the same time think we can (and
should) discuss if the change would cause practical problems.

If people want to enable an option that is not enabled by default, they
can and should prepare for consequences.

interest of kre is consistently the portable scripts, and the request
is clearly not from a practical point of view for Bash scripting he is
working on but from an aesthetic one.

I disagree. My impression is that it's not purely aesthetic, but a
semantic difference about the meaning of `unset'. He can, of course, speak
for himself.

Even from the aesthetic point of
view, the desired behavior depends on the person as we can see in the
diversity of the behavior among the shells with dynamic scoping: yash,
mksh, and osh (oilshell) (and bash until 1995 according to the
discussion), removes the placeholder of a local variable with `unset'
while zsh and posh makes the state of the local variable unset. I
actually think the behavior of yash and mksh (which is opposite to
localvar_unset) is more reasonable considering the dynamic scoping,
and I do not think the behavior of the local variables should be
always identical to the global variables (but I must admit that I
haven't followed the discussion made in 1995).

The behavior varies depending on how `purely' you view dynamic scoping.

You forgot dash and the BSDs' sh, which follow the bash behavior for the
unset-local-var-in-a-function case (let's not discuss ksh93 and its weird
mix of functions and scoping). That kind of makes yash and mksh outliers.

Anyway, as mentioned in [1], practically the most important thing was
backward compatibility for the scripts of the past 23 years

As you note, the default behavior did not change. If you change an option
from its default setting, you necessarily endanger backwards compatibility.

`shopt -s localvar_unset' affects the behavior of all
the existing libraries and frameworks [note 1].

I think a person who enables non-default behavior does so for a reason,
and that has consequences.

 The behavior change of
« unset -v var » doesn't cause problems in an independent script that
has full control of the shell options, but the frameworks and
libraries need to work under an arbitrary set of shell options
provided by the main environment (or make explicit restrictions on the
shell options of the main environment).

There are several options available to these authors, one of which is to
detect whether undesired options are enabled and warn that behavior may
not be what the user expects.

[note 1] I think it wouldn't have caused a problem if the new ``static
unset'' were introduced as a distinct option such as « unset -s var ».

Hindsight is, as always, perfect. There's a place for both alternatives.

We sometimes need to introduce backward-incompatible changes if the
old behavior causes problems or the new behavior is much better than
the old one, but I doubt that localvar_unset has a practical benefit.

Maybe not for your use. Who knows what others may do?

Since it's not enabled by default, and backwards compatibility isn't an
issue unless someone explicitly enables it, I don't consider it a
backwards-incompatible change.

The logical conclusion of your argument is that you should never introduce
new optional behavior that could cause a behavior change when the option is
enabled, since the old behavior isn't `problematic enough' or there are
available workarounds.

People have actually used this argument, but I don't think it's productive.

``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU

reply via email to

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