Chet Ramey wrote:
Yes. Once you assign a value to the local instances of the variables, they are set. Local variables inherit the exported status of the variable they are shadowing to avoid surprises in the export environment. Believe it or not, it's less surprising than letting a local variable shadow a global for everything except exporting to child processes. It's been that way forever (well, at least as far back as bash-2.05b, when I quit looking.)
--- I never knew that -- always made sure to re-export vars I wanted exported...so had never had an occasion to run into that 'feature'. Um... is it really needed/helpful to people that way?, as it surprises me more, to realize that a 'local' variable, again, isn't really just 'local'. In that regard, it's like perl, with local localizing the value of a global while it is running (or for sub-children). That leaves a opportunity -- "my"... lexically scoped local vars that disappear outside of the lexical scope (unless explicitly exported. While that doesn't sound exceptionally useful by itself -- it would ***also*** allow use of a global "read-only" name in a subroutine without worrying about whether or not your "local varname" is prohibited due to some upper level call having made it 'read only'. Any subs called by the 'sub' would see the namespace as it appeared before entering the sub with the 'my' and would see the read-only values, unchanged, as they'd be before calling the function with 'my'. I.e. 'my' vars would only let a function use any name without regard to what environment it was called from, but that name is only viewable and active from within that 1 function. I would restrict lexically scoped 'my' vars, from being exported -- as that would break the paradigm. If a user wants to store a value in a global or exported var with the same name as a lexical 'my-declared' var, then the lexical would first have to be "unset". Then any previously declared globals or exported vars by that name would be visible. ex: this would no longer fail (infinite loop): #---------------------- #!/bin/bash function printnames { local -i i #should be 'lexical override'... echo -n "Names = " for ((i=0;i<${#names[@]};++i));do echo -n "${names[i]} "; done echo "" } declare -a names=('sam' 'han' 'riker') printnames #...code.... declare -r i=2 #...code.... read -p "go on to see loop or exit ([e],g) " var if [[ $var != g ]]; then exit; fi printnames #----------------------