bug-bash
[Top][All Lists]
Advanced

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

Re: variable set in exec'ing shell cannot be unset by child shell


From: Ti Strga
Subject: Re: variable set in exec'ing shell cannot be unset by child shell
Date: Sat, 14 Oct 2023 12:55:21 -0400

On Fri, Oct 13, 2023 at 5:35 PM Chet Ramey <chet.ramey@case.edu> wrote:
> This is what happens. First, you have to remember that variables supplied
> as temporary assignments to builtins like eval and source persist for the
> entire life of that builtin's execution, and appear in the environment of
> child processes those builtins create (this is what the man page text
> "added to the environment of the executed command" means for a builtin).

Yep, that part I'm extremely familiar with...


> these temporary variables can shadow global variables.

...but I was not aware of that part in this context!  That's what I was missing.


> 6. inner.sh calls unset, which unsets the temporary variable (clone) and
>     `unshadows' the global variable (clone2)

And that makes it very clear what's going on.  Thank you for that walkthrough.


> There is code in bash to make a unsetting a function's local copy of a
> dynamically-scoped variable that shadows a global variable remain `unset'
> instead of unshadowing the global, but I've never done that for source or
> eval. It's not clear that would help in this case, either -- it depends
> on what the rest of the code does and expects.

I could see "helpful or not" going either way, honestly.  In this
specific case, there isn't really any "rest of the code" that's
relevant to the variables being shadowed, etc, it's just the "[[ -v
foo ]]" tests to see where along the cloning process we are.  The only
part I didn't include in the example was the code that does such tests
to see if it's inside the cloned copy, and if it is, arranges to
delete the temporary copy on exit.  (The arbitrary top-level script
might also be doing on-exit actions, so there's this whole thing of
registering a chain of functions to be called by the single permitted
EXIT trap.  All of that is working, and is independent of the optional
cloning, so I didn't want to litter up the example with distractions.)

Activating the code you mention for source/eval might have helped for
my particular use case, in that it would have saved me some debugging
time that I would otherwise have spent... I dunno, probably drinking
more coffee.  But it would likely have introduced confusion for all
the other users who were accustomed to the shadowing behavior, and
caused them to spend even more time debugging and writing bug report
emails.  I agree probably not helpful to have that code for
source/eval.  :-)

We'll either be writing a solid comment in the code explaining why
that particular 'unset' has to be where it is, or we'll change to
testing the values of those trigger variables instead of just "is it
set or not" and using varying values to track where in the process it
is ("clone" vs "clone2" in your example).

Thank you again!
-Ti



reply via email to

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