On Sun, Mar 10, 2024, at 1:51 PM, Kerin Millar wrote: > Dynamic scoping can be tremendously confusing. The following examples > should help to clarify the present state of affairs. > > $ x() { local a; y; echo "outer: $a"; } > $ y() { local a; a=123; echo "inner: $a"; } > $ x; echo "outermost: $a" > inner: 123 > outer: > outermost: > > This is likely as you would expect. > > $ y() { local -g a; a=123; echo "inner: $a"; } > $ x; echo "outermost: $a" > inner: 123 > outer: 123 > outermost: > > This may not be. There, the effect of the -g option effectively ends at > the outermost scope in which the variable, a, was declared. Namely, > that of the x function.
This doesn't seem to be accurate; the assignment is performed at the *innermost* declared scope (other than the "local -g" one): $ x() { local a; y; echo "outer: $a"; } $ y() { local a; z; echo "inner: $a"; } $ z() { local -g a; a=123; echo "innermost: $a"; } $ x; echo "outermost: $a" innermost: 123 inner: 123 outer: outermost: Basically, without an assignment, "local -g" does nothing. > The manual states that the "-g option forces variables to be created or > modified at the global scope, even when declare is executed in a shell > function" and that "it is ignored in all other cases". I would consider > this wording insufficient for a user to be able to effectively reason > with the difference between the second case and the other two cases > presented. Later it does say When used in a function, `declare` makes each _name_ local, as with the `local` command, unless the `-g` option is used. but that doesn't really make the consequences of -g clear either. -- vq