I have an Asus router running a recent version of FreshTomato - that comes with BusyBox.
I need to run a script that was made with BASH in mind - it is an adaptation of this script - but it fails to run with this error: line 41: syntax error: bad substitution
Checking the script with shellcheck.net yields these errors:
Line 41:
for optionvarname in ${!foreign_option_*} ; do
^-- SC3053: In POSIX sh, indirect expansion is undefined.
^-- SC3056: In POSIX sh, name matching prefixes are undefined.
Line 42:
option="${!optionvarname}"
^-- SC3053: In POSIX sh, indirect expansion is undefined.
These are the lines that are causing problems:
for optionvarname in ${!foreign_option_*} ; do # line 41
option="${!optionvarname}" # line 42
# do some stuff with $option...
done
If my understanding is correct, the original script simply does something with all variables that have a name starting with foreign_option_
However, as far as I could determine, both ${!foreign_option_*}
and ${!optionvarname}
constructs are BASH-specific and not POSIX compliant, so there is no direct "bash to sh" code conversion possible.
I have tried to create a /bin/bash
symlink that points to busybox
, but I got the Read-only file system
error.
So, how can I get this script to run on my router? I see only two options, but I cant figure out how to implement either:
- Make BusyBox interpret the script as BASH instead of SH - can I use a specific shebang for this?
- Seems like the fastest option, but only if BusyBox has a "complete" implementation of BASH
- Alter the script code to not use BASH specifics.
- This is safer, but since there is no "collect al variables starting with X" for SH, how can I do it?
That easy, either:
That doesn't make sense. Busybox comes with
ash
shell interpreter and bash is bash. Bash can interpret bash extensions, ash can't interpret them. You can't "make busybox interpret bash" - cars don't fly, planes are for that. If you want to make a car fly, you add wings to it and make it faster. The answer toMake BusyBox interpret the script as BASH instead of SH
would be: patch busybox and implement all bash extensions in it.Shebang is used to run a file under different interpreter. Using
#!/bin/bash
would invokebash
, which would be unrelated to anything busybox related and busybox wouldn't be involved in it.Decide on a unrealistic maximum, iterate over variables named
foreign_option_{1...some_max}
, for each variable see if it is set, if it is set, cotinue the script.With enough luck maybe you can use the
set
output. The following will fail if any variable contains a value as newline + the string that matches the regex:Indirect expansion can be easily replaced by
eval
: