【发布时间】:2020-10-14 07:40:08
【问题描述】:
我有一台华硕路由器,运行最新版本的 FreshTomato - BusyBox 附带。
我需要运行一个考虑到 BASH 的脚本 - 它是 this script 的改编版 - 但它无法运行并出现以下错误: line 41: syntax error: bad substitution
使用shellcheck.net 检查脚本会产生以下错误:
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.
这些是导致问题的行:
for optionvarname in ${!foreign_option_*} ; do # line 41
option="${!optionvarname}" # line 42
# do some stuff with $option...
done
如果我的理解是正确的,那么原始脚本只是对名称以foreign_option_ 开头的所有变量执行一些操作
但是,据我所知,${!foreign_option_*} 和 ${!optionvarname} 构造都是 BASH 特定的,并且不符合 POSIX,因此不可能进行直接的“bash 到 sh”代码转换。
我尝试创建一个指向busybox 的/bin/bash 符号链接,但出现Read-only file system 错误。
那么,我怎样才能让这个脚本在我的路由器上运行呢?我只看到两个选项,但我不知道如何实现:
- 让 BusyBox 将脚本解释为 BASH 而不是 SH - 我可以为此使用特定的 shebang 吗?
- 似乎是最快的选择,但前提是 BusyBox 具有 BASH 的“完整”实现
- 更改脚本代码以不使用 BASH 细节。
- 这样比较安全,但是由于 SH 没有“收集以 X 开头的变量”,我该怎么做?
【问题讨论】:
-
set | grep -e "^X"收集以X开头的变量名怎么样? -
sh不提供变量间接寻址,例如${!optionvarname},它试图评估名称存储在optionvarname中的变量。这是导致“错误替换”的仅限 bash 的功能......请注意您的错误消息"In POSIX sh, indirect expansion is undefined."- 这就是告诉您的内容...... -
@DavidC.Rankin:我发现了这个问题,但遗憾的是我并不那么精通
bash/sh的差异和复杂性,以便能够进行适当的转换,因此寻求帮助
标签: bash sh parameter-expansion