On Mon, Jan 24, 2022 at 12:11:33PM -0800, Junio C Hamano wrote: > Even though this message ends with a patch that could be applied to > your tree, it is not for application at all. It is to demonstrate a > potential problem in the code in our tree. > > While I was playing with the "Linux development environment (beta)" > on one of my Chromebooks, I say its default /bin/sh (which is Dash > 0.5.10) mishandled this construct: > > func () { > local x=$1 > clobber x and nothing else and feel safe > message="I expect this to be visible by the caller" > } > > func "a message" > use "$message" > > It assigned 'a' to $x in the function, DECLARED the varilable > $message as local to the function, hence the caller after func > returned did not see what I intended to see in $message. > > The breakage is subtle; unless you have a character in $1 that would > not make a valid variable name, you won't get any error message yet > the program would behave in an unexpected way. Sorry, I might have not followed the entire thread, but assignment in `local` is a bashism, and dash can only handle the declaration part with `local`, not assignment; hence the safe code should read local x x="$1" To cite the dash manual page: | Variables may be declared to be local to a function by using a local | command. This should appear as the first statement of a function, and the | syntax is | | local [variable | -] ... | | Local is implemented as a builtin command. | | When a variable is made local, it inherits the initial value and exported | and readonly flags from the variable with the same name in the surrounding | scope, if there is one. Otherwise, the vari‐ able is initially unset. The | shell uses dynamic scoping, so that if you make the variable x lo‐ cal to | function f, which then calls function g, references to the variable x made | inside g will refer to the variable x declared inside f, not to the global | variable named x. | | The only special parameter that can be made local is “-”. Making “-” local | any shell options that are changed via the set command inside the function | to be restored to their original values | when the function returns.