在网上查了发现关于这一方面的都没有详细的说明,搞得人一头雾水,如果不清楚里面是如何实现的,那么这些openwrt下shell脚本根本就看不下去了。没有详细的资料,唯有自己研究了。
Shell脚本中获取文件信息主要依靠于以下几个shell函数:config_load,config_get,config_set.
以解读配置文件/etc/config/wireless为例
/etc/config/wireless内容:
config wifi-device 'wifi0'
option type 'qcawifi'
option channel 'auto'
option txpower 'auto'
option bcnburst '1'
option hwmode '11ng'
option disabled '0'
option country 'US'
.........
执行以下命令:/sbin/wifi reload
/sbin/wifi:
......
DEVICES=
DRIVERS=
include /lib/wifi
scan_wifi
case "$1" in
down) wifi_updown "disable" "$2";;
detect) wifi_detect "$2";;
status) ubus_wifi_cmd "status" "$2";;
reload) wifi_reload "$2";;
reload_legacy) wifi_reload_legacy "$2";;
flush) flush_wifi "$2" "$3" "$4";;
update) update_wifi "$2" "$3" "$4";;
radio_update) radio_update_wifi $@;;
global) global_wifi $@;;
--help|help) usage;;
*) ubus call network reload; wifi_updown "enable" "$2";;
esac
首先执行了scan_wifi
scan_wifi() {
local cfgfile="$1"
DEVICES=
config_cb() {
local type="$1"
local section="$2"
# section start
case "$type" in
wifi-device)
append DEVICES "$section"
config_set "$section" vifs ""
config_set "$section" ht_capab ""
;;
esac
# section end
config_get TYPE "$CONFIG_SECTION" TYPE
case "$TYPE" in
wifi-iface)
config_get device "$CONFIG_SECTION" device
config_get vifs "$device" vifs
append vifs "$CONFIG_SECTION"
config_set "$device" vifs "$vifs"
;;
esac
}
config_load "${cfgfile:-wireless}"
}
其主要执行了config_load "${cfgfile:-wireless}"即:config_load wireless
在/lib/functions文件定义了config_load
config_load() {
[ -n "$IPKG_INSTROOT" ] && return 0
uci_load "$@"
}
Config_load里面执行uci_load wireless
在/lib/config/uci.sh中
uci_load() {
local PACKAGE="$1"
local DATA
local RET
local VAR
_C=0
if [ -z "$CONFIG_APPEND" ]; then
for VAR in $CONFIG_LIST_STATE; do
export ${NO_EXPORT:+-n} CONFIG_${VAR}=
export ${NO_EXPORT:+-n} CONFIG_${VAR}_LENGTH=
done
export ${NO_EXPORT:+-n} CONFIG_LIST_STATE=
export ${NO_EXPORT:+-n} CONFIG_SECTIONS=
export ${NO_EXPORT:+-n} CONFIG_NUM_SECTIONS=0
export ${NO_EXPORT:+-n} CONFIG_SECTION=
fi
DATA="$(/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} ${LOAD_STATE:+-P /var/state} -S -n export "$PACKAGE" 2>/dev/null)"
RET="$?"
[ "$RET" != 0 -o -z "$DATA" ] || eval "$DATA"
unset DATA
${CONFIG_SECTION:+config_cb}
return "$RET"
}
这段最关键的是:
DATA="$(/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} ${LOAD_STATE:+-P /var/state} -S -n export "$PACKAGE" 2>/dev/null)"
执行完后:
Date={config wifi-device 'wifi0'
option type 'qcawifi'
option channel 'auto'
option txpower 'auto'
option bcnburst '1'
option hwmode '11ng'
option disabled '0'
option country 'US'
.........
}
这句很关键:[ "$RET" != 0 -o -z "$DATA" ] || eval "$DATA"
这句意思是:执行date变量的内容即date变量内容的每一行都是一条执行命令:
date变量内容的第一行是:
config wifi-device 'wifi0’
表示:config是可执行的函数或命令,$1=wifi-device $2=wifi0
在/lib/function中:
config () {
local cfgtype="$1"
local name="$2"
export ${NO_EXPORT:+-n} CONFIG_NUM_SECTIONS=$(($CONFIG_NUM_SECTIONS + 1))
name="${name:-cfg$CONFIG_NUM_SECTIONS}"
append CONFIG_SECTIONS "$name"
[ -n "$NO_CALLBACK" ] || config_cb "$cfgtype" "$name"
export ${NO_EXPORT:+-n} CONFIG_SECTION="$name"
export ${NO_EXPORT:+-n} "CONFIG_${CONFIG_SECTION}_TYPE=$cfgtype"
}
append() {
local var="$1"
local value="$2"
local sep="${3:- }"
eval "export ${NO_EXPORT:+-n} -- \"$var=\${$var:+\${$var}\${value:+\$sep}}\$value\""
}
执行后可得到:
CONFIG_SECTIONS=wifi0
CONFIG_SECTIONS__TYPE=wifi-device
对于option:
如:option type 'qcawifi'
option () {
local varname="$1"; shift
local value="$*"
export ${NO_EXPORT:+-n} "CONFIG_${CONFIG_SECTION}_${varname}=$value"
[ -n "$NO_CALLBACK" ] || option_cb "$varname" "$*"
}
执行后可得到:
CONFIG_wifi0_type=qcawifi
依据上面,所有配置文件信息在config_load执行完后,配置信息都导出到了对应shell的变量中了
我们要获取变量信息是很容易了
主要通过以下函数获取和设置:
config_get() {
case "$3" in
"") eval echo "\${CONFIG_${1}_${2}:-\${4}}";;
*) eval export ${NO_EXPORT:+-n} -- "${1}=\${CONFIG_${2}_${3}:-\${4}}";;
esac
}
config_set() {
local section="$1"
local option="$2"
local value="$3"
local old_section="$CONFIG_SECTION"
CONFIG_SECTION="$section"
option "$option" "$value"
CONFIG_SECTION="$old_section"
}
如:
config_get disabled "$device" disabled这个命令
执行是:
eval export ${NO_EXPORT:+-n} -- "${1}=\${CONFIG_${2}_${3}:-\${4}}";;
即:
disabled =$(CONFIG_wifi_disabled)
自此:解读就很清晰了
config_load将配置文件信息导出到shell变量中
Config_get获取shell变量的值
Config_set设置shell变量的值