如何解决转换BASH脚本以在SH上运行通过BusyBox
我有一个运行FreshTomato最新版本的Asus路由器-BusyBox随附。
我需要运行一个考虑到BASH的脚本-它是this script的改编版-但由于以下错误而无法运行:0
使用shellcheck.net检查脚本会产生以下错误:
line 41: Syntax error: bad substitution
以下是引起问题的行:
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_*}
构造都是BASH特定的,并且不兼容POSIX,因此不可能直接进行“ bash到sh”的代码转换。
我试图创建一个指向${!optionvarname}
的{{1}}符号链接,但是出现了/bin/bash
错误。
那么,如何使此脚本在路由器上运行?我只看到两个选项,但我无法弄清楚如何实现:
- 使BusyBox将该脚本解释为BASH而不是SH-我可以为此使用特定的shebang吗?
- 似乎是最快的选择,但前提是BusyBox具有“完全”的BASH实现
- 更改脚本代码以不使用BASH细节。
- 这比较安全,但是由于SH没有“以X开头的al变量”,我该怎么办?
解决方法
如何让此脚本在路由器上运行?
那么容易,要么:
- 在路由器上安装bash或
- 将脚本移植到busybox / posix兼容shell。
使BusyBox将脚本解释为BASH而不是SH-我可以为此使用特定的shebang吗?
那没有道理。 Busybox随附ash
Shell解释器,bash为bash。 Bash可以解释bash扩展名,ash无法解释它们。您不能“让busybox解释bash”-汽车不飞,飞机不适合飞。如果要使汽车飞行,则可以在其上添加翼子并使其更快。对Make BusyBox interpret the script as BASH instead of SH
的答案是:修补busybox并在其中实现所有bash扩展。
Shebang用于在不同解释器下运行文件。使用#!/bin/bash
会调用bash
,它与与busybox相关的任何内容都不相关,并且也不涉及busybox。
我该怎么办?
确定一个不切实际的最大值,遍历名为foreign_option_{1...some_max}
的变量,对于每个变量,请查看是否已设置(如果已设置),脚本的连续性。
for i in $(seq 100); do
optionvarname="foreign_option_${i}"
# https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash
if eval "[ -z \"\${${optionvarname}+x}\" ]"; then continue; fi;
如果有足够的运气,也许您可以使用set
输出。如果任何变量包含换行符和与正则表达式匹配的字符串,则以下内容将失败:
for optionvarname in $(set | grep -o '^foreign_option_[0-9]\+=' | sed 's/=//'); then
间接扩展可以很容易地用eval
代替:
eval "option=\"\$${optionvarname}\""
,
如果您确实无法在该路由器上安装Bash,这是一种可能的解决方法,它似乎在Qnap NAS上的BusyBox中对我有用:
foreign_option_one=1
foreign_option_two=2
for x in one two; do
opt_var=foreign_option_${x}
eval "opt_value=\$$opt_var"
echo "$opt_var = $opt_value"
done
(但是将Bash脚本移至busybox可能会遇到更多问题,因此您可能首先要考虑其他方法,例如更换路由器)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。