[PATCH] RFC: nvedit: support doing one (extra) expansion of the value in "env set"

Rasmus Villemoes rasmus.villemoes at prevas.dk
Thu Feb 13 11:41:24 CET 2020

On 12/02/2020 12.38, Wolfgang Denk wrote:
> Dear Rasmus,
> In message <c48f9de9-ad02-3b45-ae2e-50c3086d6a68 at prevas.dk> you wrote:
>>> HUSH does not support arrays anyway...
>> Of course not, but they can be emulated by having variables foo0, foo1,
>> foo2 and programmatically accessing the variable foo$index, if only
>> there's a way to do that... In a sense, my BOOT_A_LEFT/BOOT_B_LEFT is
>> also just an array with keys "A" and "B".
> Actually the port to U-Boot cripples HUSH in many more aspects.
> I've always hoped someone would some day volunteer and (1)( update
> HUSH to a more recent (and less buggy) version and address a few of
> the missing parts, like Command Substitution, which would be really
> handy in many cases - here as well.

I'm certainly also missing break (and to a lesser extent continue) in loops.

>>> Well, there _are_ other ways...
>> Please do tell. How can I avoid code duplication and access a variable
>> whose name I generate by string concatenation/variable interpolation?
>> I.e., I don't want anything like "if test $slot = "A" ; then setenv
>> result BOOT_A_LEFT ; elif test $slot = "B" ; then setenv result
>> BOOT_B_LEFT ; fi", because that doesn't scale.
> => slot=A
> => setenv result BOOT_${slot}_LEFT
> => printenv result
> result=BOOT_A_LEFT
> => setenv foo 'setenv result BOOT_${slot}_LEFT; printenv result'
> => slot=B
> => run foo
> result=BOOT_B_LEFT
> => slot=X
> => run foo
> result=BOOT_X_LEFT
> What exactly is your question?

I'm sorry, I see I mistyped in my example above, it should have been

  if test $slot = "A" ; setenv result $BOOT_A_LEFT ...

as should hopefully be clear from the original post and the eval
examples. So to reiterate, the problem is to get the contents (or value,
if you will) of the BOOT_A_LEFT variable into the result variable, not
setting result to the string "BOOT_A_LEFT" - but with the wrinkle that
BOOT_A_LEFT is generated programmatically, so the code cannot literally
mention BOOT_A_LEFT anywhere.

>>   env set -E result "\${BOOT_${x}_LEFT}"
>> corresponds to
>>   eval "result=\${BOOT_${x}_LEFT}"
> ...and things become already very tricky here, as you can see from
> the need of having "\$" and "$" mixed. Now assume you have more of
> this in the embedded variables...

Eh, yes, exactly as one needs to do in ordinary shells when using the
eval construct. I don't see how one can on the one hand trust
programmers to have arbitrary read and write access to all of physical
memory but not trust them to get such rather basic escaping right (and
testing should immediately show if one got it wrong).

I also proposed an escape-less solution, namely "env get". That would be
slightly less powerful, since

env get dest whatever

could be implemented in terms of "env set -E" as

env set -E dest "\${whatever}"

but as I said, I think that would be sufficient for my purposes.

So just as print[env] takes the name of a variable and shows the
name=value string, and one can thus say "printenv BOOT_${slot}_LEFT" as
you did in your extended example, I could do

  env get result BOOT_${slot}_LEFT

and get the value of the BOOT_${slot}_LEFT variable into result.

Would you be ok with adding such an "env get" with less foot-gun potential?


More information about the U-Boot mailing list