[Toybox] Bug: can't execute a shell function via variable in toybox shell
Rob Landley
rob at landley.net
Fri Feb 28 19:39:45 PST 2025
On 2/27/25 14:45, Bird, Tim wrote:
> Hey Rob,
>
> I indirectly reported this on a separate thread, but here's a more complete bug report,
> with steps to reproduce.
>
> If I define a shell function in bash, I can execute the function by putting its name
> in a variable, and then retrieving the value of the variable at the shell interpreter prompt,
> like so:
>
> On my desktop machine, running the bash shell:
> tbird at timdesk:~$ myfunc() {
>> echo "inside myfunc"
>> }
> tbird at timdesk:~$ myfunc
> inside myfunc
> tbird at timdesk:~$ VAR="myfunc"
> tbird at timdesk:~$ $VAR
> inside myfunc
>
> This doesn't work with the toybox shell. I get "sh: <func_name>: No such file or directory"
>
> When running a toybox shell under qemu, I get the following:
> $ myfunc() {
>> echo "inside myfunc"
>> }
> $ myfunc
> inside myfunc
> $ VAR="myfunc"
> $ $VAR
> sh: myfunc: No such file or directory
> $
>
> Note that executing an internal or external command from a variable reference works:
> $ VAR="echo hello"
> $ $VAR
> hello
> $ VAR="cat /etc/passwd"
> $ $VAR
> root:x:0:0:root:/root:/bin/sh
> guest:x:500:500:guest:/home/guest:/bin/sh
> nobody:x:65534:65534:nobody:/proc/self:/dev/null
> $
Sigh, the sequencing there is fiddly. Aliases are parsed before variable
expansion:
$ alias xyz=potato
$ XYZ=xyz
$ $XYZ
bash: xyz: command not found
$ alias xyz='$XYZ'
$ XYZ=potato
$ xyz
bash: potato: command not found
But function names are parsed afterwards. Ok...
Alias is still on my todo heap because I do NOT understand bash's
escaping behavior for alias. Alias with no arguments and alias -p seem
to produce identical output (fine), but:
$ alias walrus=$'abc\'def'; alias
alias walrus='abc'\''def'
$ alias walrus=$'abc\\\'def'; alias
alias walrus='abc\'\''def'
$ walrus
bash: abc'def: command not found
$ echo $'abc\\\'def'
abc\'def
$ alias walrus=$'abc\\\\\'def'
$ walrus
> ^C
$ alias
alias walrus='abc\\'\''def'
$ alias walrus=$'abc\\ndef'; alias$ alias -p
alias walrus='abc\ndef'
$ walrus
bash: abcndef: command not found
It's _simultaneously_ treating backslash as special and as not special
and I do NOT understand what it's doing and half the time I ask Chet he
changes the behavior so my TEST_HOST tests don't behave consistently on
old versions new bash and "what success looks like" disappears under
version skew. (If my test doesn't pass against the reference version,
what am I really testing?)
Also, -p means "print before assigning" which is just strange. Exact
same output, not a different format, and:
$ alias -p one=two
alias walrus='abc\ndef'
$ one
bash: two: command not found
Ahem. Sorry. This is what cloning bash is like. When you poke at the
corner cases, it's not so much designed as accumulated.
Anyway, I should fix up the function sequencing THEN tackle aliases...
> Thanks,
> -- Tim
Thanks for the heads up,
Rob
More information about the Toybox
mailing list