https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=296207
Bug ID: 296207
Summary: bin/sh: Don't inherit variables declared local by
default
Product: Base System
Version: CURRENT
Hardware: Any
OS: Any
Status: New
Severity: Affects Only Me
Priority: ---
Component: bin
Assignee: [email protected]
Reporter: [email protected]
The vast majority of shells don't do that.
Here's a simple example:
------------------------
#!/bin/sh
func2()
{
local myvar
echo "myvar: ${myvar}"
}
func1()
{
local myvar="hello"
func2
}
func1
------------------------
The output of this script (#!/bin/sh) is:
------------------------
myvar: hello
------------------------
but if we make Bash the interpreter (#!/usr/local/bin/bash), the output will
be:
------------------------
myvar:
------------------------
To me, personally, it's not very intuitive and convenient behaviour (even
though it's documented in the manual page): the fact of inheritance when
variable is declared local, but is not initialized explicitly makes it harder
to write helper functions (when function calls another function). In practice,
people usually write shell functions like this:
------------------------
function foo()
{
local v1 v2 v3
}
------------------------
I.e., in case they don't need an initializer for the variable - they don't
explicitly specify it. But I personally would expect that v1, v2 and v3 are
initially unset in this case. And the knowledge of whether that's true or not
is important, because further logic in the function may rely on the fact, that
these variables were initially unset. In other words, I believe people would
more frequently need such variables to be unset, rather than inherited from
parent scope.
NetBSD (from which FreeBSD's /bin/sh is derived) addressed this issue in 2017:
https://github.com/NetBSD/src/commit/8df083c1040caf66e57a260f095b82a6c29a510f.
They introduced additional flags to 'local', that allow to enable or disable
inheritance, and they left the enabled inheritance (-I) as a default behaviour.
I believe this would be a nice change to have in FreeBSD as well.
Unfortunately, I suppose that we are not able to turn off the inheritance by
default, are we? It may cause some problems with existing /bin/sh scripts in
FreeBSD? But I guess though that this may affect FreeBSD /bin/sh scripts only,
because almost all shells don't do the inheritance by default, and our shell is
the minority. But maybe this would be easier to correct FreeBSD /bin/sh script
problems, that may appear after this change, but have an expected behaviour
that matches other shells as the result? Or, if that would not be feasible,
then it seems that a new option for disabling the inheritance is the only
choice. But then we would have to write functions like this:
------------------------
function foo()
{
local -N v1 v2 v3
}
------------------------
if we want a de facto 'standard' behaviour that almost all modern shells have.
This kind of doesn't look idiomatic anymore. Yes, 'local' is not POSIX, but,
if we already have it, I think it's better to match the most de facto common
behaviour out there.
These are my thoughts, I'd be glad to get some feedback.
--
You are receiving this mail because:
You are the assignee for the bug.