'eval' command: ash (OpenWrt) vs bash (ubuntu)

I have initially built script using eval for OpenWrt, where did the following:

	VARNAME=$"ID$(printf "%d" $NUM)"
	eval VALUE="$VARNAME"

where the first line makes $VARNAME to be $ID0 in case $NUM is 0, and the second line takes contents of the shell variable called $ID0 into $VALUE.

I wanted to port this code onto the Ubuntu, and was astonished to see it does not work. Ubuntu wants second line to be

	eval VALUE='$'$VARNAME

Furthermore, this eval VALUE='$'$VARNAME does not work on OpenWrt.

Please advise where is the issue here. I thought eval to be portable between these operating systems...

no, it may not be portable among various *nix shells not among *nix OS variants . there are many differences what and how a shell is supporting. ash is a very lightweight shell, bash is not following the original unix features etc.

and by the way: first line makes $VARNAME to be $ID0 in ash.

root@fw:~# NUM=0
root@fw:~# VARNAME=$"ID$(printf "%d" $NUM)"
root@fw:~# echo $VARNAME
$ID0
root@fw:~# eval VALUE="$VARNAME"
root@fw:~# echo $VALUE
root@fw:~# ID0=1
root@fw:~# eval VALUE="$VARNAME"
root@fw:~# echo $VALUE
1

# and you are right bash works differently
root@fw:~# bash
root@fw:~# NUM=0
root@fw:~# VARNAME=$"ID$(printf "%d" $NUM)"
root@fw:~# echo $VARNAME
ID0
root@fw:~# ID0=1
root@fw:~# eval VALUE="$VARNAME"
root@fw:~# echo $VALUE
ID0
root@fw:~# eval VALUE='$'"$VARNAME"
root@fw:~# echo $VALUE
1

1 Like

This should be a more portable alternative:

ID1=42
NUM=1
eval VALUE="\$ID$NUM"
echo $VALUE
2 Likes

@grrr2 and @bkil thank you very much.

  1. I found here that eval is evil. Is there any alternative? ${!<varable name>} does not work, declare does not work.

  2. how to assign to the variable? In other words, ID_x variable must be assigned with some value (of other variable or a constant).

Thank you!

you seem to be familiar with bash, then use bash: opkg update && opkg install bash. then set shebang to bash in your script.

my point was actually that if you want portable shell script you should forget bash-ism, like declare. but there are plenty of shells sh, csh, tcsh, zsh, bash, ash and many more, they are very different so I'd analyze your specific use case: if you can use bash on all your targets, let use bash. if you have mixed environment you either go to common minimum, or write your logic like first check shell then use shell specific code.

what @bkil suggested is a good solution by the way, and now you know that drawbacks of eval so you can prepare countermeasures.

No, I just can't find info relevant to ash used in the OpenWrt. I need minimal configuration possible and will not install anything just to be convenient. Target is default ash.

@bkil deleted his post. I did not see the suggestion!

What I desperately need right now is assigning variable pointed by another variable - as anything I find does not work in ash. While eval is evil I am ok to accept the risk right now.

you mean you cannot see his/her earlier post 'eval' command: ash (OpenWrt) vs bash (ubuntu) - #3 by bkil ???

1 Like

no, #5 was deleted - as it is, I can't know its value. #3 is visible and appreciated :slight_smile:

I realized I was redundant after going through the link posted just above. Assigning can be found in 1a:

If you are only using it via a controlled integer counter within your own script, I can't see What Can Go Wrong? :tm:

Mind you that much better answers could be given if you clarified what your exact problem is that you are trying to solve.

1 Like

Funny enough I actually have seen it, but did not get this is what I need :crazy_face:
It seems working in ash, thank you very much!

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.